Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of UniGraphic by
Revision 7:bb0383b91104, committed 2015-02-17
- Comitter:
- Geremia
- Date:
- Tue Feb 17 11:02:06 2015 +0000
- Parent:
- 6:8356d48a07db
- Child:
- 8:26757296c79d
- Commit message:
- TFT: added get deviceID, scroll functions
Changed in this revision
--- a/Display/LCD.cpp Mon Feb 16 01:18:29 2015 +0000
+++ b/Display/LCD.cpp Tue Feb 17 11:02:06 2015 +0000
@@ -21,40 +21,29 @@
#include "LCD.h"
//#include "mbed_debug.h"
-//#define LCDPAGES (LCDSIZE_Y>>3) // 8raws per page
-//#define IC_PAGES (IC_Y_COMS>>3) // max pages in IC ddram, 8raws per page
+
#define SWAP(a, b) { a ^= b; b ^= a; a ^= b; }
-//#define USEFRAMEBUFFER
-
-//#define FRAMEBUFSIZE (LCDSIZE_X*LCDPAGES)
LCD::LCD(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char *name)
- : /*PAR8(port, CS, reset, DC, WR, RD),*/ GraphicsDisplay(name), LCDSIZE_X(lcdsize_x), LCDSIZE_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)
+ : 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)
{
- // LCDPAGES = LCDSIZE_Y>>3;
- // IC_PAGES = IC_Y_COMS>>3;
- // buffer = new unsigned char [LCDSIZE_X*LCDPAGES];
- // PAR8 par8proto(port, CS, reset, DC, WR, RD);
if(displayproto==PAR_8) proto = new PAR8(port, CS, reset, DC, WR, RD);
useNOP=false;
- buffer = (unsigned char*) malloc (LCDSIZE_X*LCDPAGES);
+ buffer = (unsigned char*) malloc (screensize_X*_LCDPAGES);
buffer16 = (unsigned short*)buffer;
draw_mode = NORMAL;
set_orientation(1);
foreground(White);
background(Black);
set_auto_up(true);
+ tftID=0;
// cls();
// locate(0,0);
}
LCD::LCD(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char *name)
- : GraphicsDisplay(name), LCDSIZE_X(lcdsize_x), LCDSIZE_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)
+ : 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)
{
- // LCDPAGES = LCDSIZE_Y>>3;
- // IC_PAGES = IC_Y_COMS>>3;
- // buffer = new unsigned char [LCDSIZE_X*LCDPAGES];
- // PAR8 par8proto(port, CS, reset, DC, WR, RD);
if(displayproto==SPI_8)
{
proto = new SPI8(Hz, mosi, miso, sclk, CS, reset, DC);
@@ -65,7 +54,7 @@
proto = new SPI16(Hz, mosi, miso, sclk, CS, reset, DC);
useNOP=true;
}
- buffer = (unsigned char*) malloc (LCDSIZE_X*LCDPAGES);
+ buffer = (unsigned char*) malloc (screensize_X*_LCDPAGES);
buffer16 = (unsigned short*)buffer;
draw_mode = NORMAL;
// cls();
@@ -73,6 +62,7 @@
foreground(White);
background(Black);
set_auto_up(true);
+ tftID=0;
// locate(0,0);
}
@@ -122,33 +112,33 @@
case (0):// portrait view -90°
mirrorXY(Y);
col_offset = 0;
- page_offset = IC_PAGES-LCDPAGES;
- set_width(LCDSIZE_Y);
- set_height(LCDSIZE_X);
+ page_offset = _IC_PAGES-_LCDPAGES;
+ set_width(screensize_Y);
+ set_height(screensize_X);
// portrait = true;
break;
case (1): // default, landscape view 0°
mirrorXY(NONE);
col_offset = 0;
page_offset = 0;
- set_width(LCDSIZE_X);
- set_height(LCDSIZE_Y);
+ set_width(screensize_X);
+ set_height(screensize_Y);
// portrait = false;
break;
case (2):// portrait view +90°
mirrorXY(X);
- col_offset = IC_X_SEGS-LCDSIZE_X; // some displays have less pixels than IC ram
+ col_offset = _IC_X_SEGS-screensize_X; // some displays have less pixels than IC ram
page_offset = 0;
- set_width(LCDSIZE_Y);
- set_height(LCDSIZE_X);
+ set_width(screensize_Y);
+ set_height(screensize_X);
// portrait = true;
break;
case (3):// landscape view +180°
mirrorXY(XY);
- col_offset = IC_X_SEGS-LCDSIZE_X;
- page_offset = IC_PAGES-LCDPAGES;
- set_width(LCDSIZE_X);
- set_height(LCDSIZE_Y);
+ col_offset = _IC_X_SEGS-screensize_X;
+ page_offset = _IC_PAGES-_LCDPAGES;
+ set_width(screensize_X);
+ set_height(screensize_Y);
// portrait = false;
break;
}
@@ -251,43 +241,51 @@
{
if(!(orientation&1)) SWAP(x,y);
// first check parameter
- if((x >= LCDSIZE_X) || (y >= LCDSIZE_Y)) return;
+ if((x >= screensize_X) || (y >= screensize_Y)) return;
// if(draw_mode == NORMAL)
// {
- if(color) buffer[(x + ((y>>3)*LCDSIZE_X))^1] &= ~(1 << (y&7)); // erase pixel
- else buffer[(x + ((y>>3)*LCDSIZE_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
// }
// else
// { // XOR mode
-// if(color == 1) buffer[x + ((y>>3) * LCDSIZE_X)] ^= (1 << (y&7)); // xor pixel
+// if(color == 1) buffer[x + ((y>>3) * screensize_X)] ^= (1 << (y&7)); // xor pixel
// }
}
void LCD::copy_to_lcd(void)
{
unsigned short i=0;
unsigned short setcolcmd = 0x0010 | ((col_offset&0xF)<<8) | (col_offset>>4);
- for(int page=0; page<LCDPAGES; page++)
+ for(int page=0; page<_LCDPAGES; page++)
{
// wr_cmd8(col_offset&0xF); // set column low nibble
// wr_cmd8(0x10|(col_offset>>4)); // set column hi nibble
wr_cmd16(setcolcmd);
wr_cmd8(0xB0|(page+page_offset)); // set page
- wr_grambuf(buffer16+i, LCDSIZE_X>>1); // send whole page pixels
- i+=LCDSIZE_X>>1;
+ wr_grambuf(buffer16+i, screensize_X>>1); // send whole page pixels
+ i+=screensize_X>>1;
}
}
void LCD::cls(void)
{
unsigned short tmp = _background^0xFFFF;
- memset(buffer,tmp,LCDSIZE_X*LCDPAGES); // clear display buffer
+ memset(buffer,tmp,screensize_X*_LCDPAGES); // clear display buffer
unsigned short setcolcmd = 0x0010 | ((col_offset&0xF)<<8) | (col_offset>>4);
- for(int page=0; page<LCDPAGES; page++)
+ for(int page=0; page<_LCDPAGES; page++)
{
// wr_cmd8((unsigned char)col_offset&0xF); // set column low nibble
// wr_cmd8(0x10|(col_offset>>4)); // set column hi nibble
wr_cmd16(setcolcmd);
wr_cmd8(0xB0|(page+page_offset)); // set page
- wr_gram(tmp, LCDSIZE_X>>1); // send whole page pixels =0
+ wr_gram(tmp, screensize_X>>1); // send whole page pixels =0
}
+}
+int LCD::sizeX()
+{
+ return screensize_X;
+}
+int LCD::sizeY()
+{
+ return screensize_Y;
}
\ No newline at end of file
--- a/Display/LCD.h Mon Feb 16 01:18:29 2015 +0000
+++ b/Display/LCD.h Tue Feb 17 11:02:06 2015 +0000
@@ -53,9 +53,6 @@
*/
virtual void pixel(int x, int y, unsigned short color);
-
-
-
/** Set the window, which controls where items are written to the screen.
* When something hits the window width, it wraps back to the left side
* and down a row. If the initial write is outside the window, it will
@@ -66,6 +63,8 @@
* @param h is the window height in pixels.
*/
virtual void window(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 in loop.
@@ -102,7 +101,7 @@
*/
int get_contrast(void);
- /** invert the screen
+ /** display inverted colors
*
* @param o = 0 normal, 1 invert
*/
@@ -114,10 +113,6 @@
*/
virtual void cls();
-
-
-
-
/** Set the orientation of the screen
* x,y: 0,0 is always top left
*
@@ -135,6 +130,29 @@
*/
virtual void BusEnable(bool enable);
+ /** get display X size in pixels (native, orientation independent)
+ * @returns X size in pixels
+ */
+ int sizeX();
+
+ /** get display X size in pixels (native, orientation independent)
+ * @returns screen height in pixels.
+ */
+ int sizeY();
+
+////////////////////////////////////////////////////////////////////////////////
+ // not implemented yet
+//////////////////////////////////////////////////////////////////
+ virtual unsigned short pixelread(int x, int y){return 0;};
+ virtual void window4read(int x, int y, int w, int h){};
+ void setscrollarea (int startY, int areasize){};
+ void scroll (int lines){};
+ void scrollreset(){};
+
+ unsigned int tftID;
+
+
+
protected:
@@ -196,12 +214,12 @@
Protocols* proto;
unsigned char *buffer;
unsigned short *buffer16;
- const int LCDSIZE_X;
- const int LCDSIZE_Y;
- const int LCDPAGES;
- const int IC_X_SEGS;
- const int IC_Y_COMS;
- const int IC_PAGES;
+ const int screensize_X;
+ const int screensize_Y;
+ const int _LCDPAGES;
+ const int _IC_X_SEGS;
+ const int _IC_Y_COMS;
+ const int _IC_PAGES;
int page_offset;
int col_offset;
--- a/Display/TFT.cpp Mon Feb 16 01:18:29 2015 +0000
+++ b/Display/TFT.cpp Tue Feb 17 11:02:06 2015 +0000
@@ -23,7 +23,7 @@
#define SWAP(a, b) { a ^= b; b ^= a; a ^= b; }
TFT::TFT(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const char *name)
- : GraphicsDisplay(name), LCDSIZE_X(lcdsize_x), LCDSIZE_Y(lcdsize_y)
+ : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y)
{
if(displayproto==PAR_8) proto = new PAR8(port, CS, reset, DC, WR, RD);
else if(displayproto==PAR_16) proto = new PAR16(port, CS, reset, DC, WR, RD);
@@ -34,11 +34,13 @@
foreground(White);
background(Black);
set_auto_up(false); //we don't have framebuffer
+ topfixedareasize=0;
+ scrollareasize=0;
// cls();
// locate(0,0);
}
TFT::TFT(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const int lcdsize_x, const int lcdsize_y, const char *name)
- : GraphicsDisplay(name), LCDSIZE_X(lcdsize_x), LCDSIZE_Y(lcdsize_y)
+ : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y)
{
if(displayproto==SPI_8)
{
@@ -56,6 +58,8 @@
foreground(White);
background(Black);
set_auto_up(false);
+ topfixedareasize=0;
+ scrollareasize=0;
// locate(0,0);
}
void TFT::wr_cmd8(unsigned char cmd)
@@ -83,13 +87,17 @@
{
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());
+ return proto->rd_gram();
+ }
+unsigned int TFT::rd_reg_data32(unsigned char reg)
+ {
+ return proto->rd_reg_data32(reg);
+ }
+unsigned int TFT::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd)
+ {
+ return proto->rd_extcreg_data32(reg, SPIreadenablecmd);
}
//for TFT, just send data, position counters are in hw
void TFT::window_pushpixel(unsigned short color)
@@ -121,29 +129,34 @@
case 0:// default, portrait view 0°
if(mipistd) wr_data8(0x0A); // this is in real a vertical flip enabled, seems most displays are vertical flipped
else wr_data8(0x48); //for some other ILIxxxx
- set_width(LCDSIZE_X);
- set_height(LCDSIZE_Y);
+ set_width(screensize_X);
+ set_height(screensize_Y);
break;
case 1:// landscape view +90°
if(mipistd) wr_data8(0x28);
else wr_data8(0x29);//for some other ILIxxxx
- set_width(LCDSIZE_Y);
- set_height(LCDSIZE_X);
+ set_width(screensize_Y);
+ set_height(screensize_X);
break;
case 2:// portrait view +180°
if(mipistd) wr_data8(0x09);
else wr_data8(0x99);//for some other ILIxxxx
- set_width(LCDSIZE_X);
- set_height(LCDSIZE_Y);
+ set_width(screensize_X);
+ set_height(screensize_Y);
break;
case 3:// landscape view -90°
if(mipistd) wr_data8(0x2B);
else wr_data8(0xF8);//for some other ILIxxxx
- set_width(LCDSIZE_Y);
- set_height(LCDSIZE_X);
+ set_width(screensize_Y);
+ set_height(screensize_X);
break;
}
}
+void TFT::invert(unsigned char o)
+{
+ if(o == 0) wr_cmd8(0x20);
+ else wr_cmd8(0x21);
+}
// TFT have both column and raw autoincrement inside a window, with internal counters
void TFT::window(int x, int y, int w, int h)
{
@@ -186,10 +199,70 @@
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::setscrollarea (int startY, int areasize) // ie 0,480 for whole screen
+{
+ unsigned int bfa;
+ topfixedareasize=startY;
+ scrollareasize=areasize;
+ wr_cmd8(0x33);
+ wr_data16(topfixedareasize); //num lines of top fixed area
+ wr_data16(scrollareasize+scrollbugfix); //num lines of vertical scroll area, +1 for ILI9481 fix
+ if((areasize+startY)>height()) bfa=0;
+ else bfa = height()-(areasize+startY);
+ wr_data16(bfa); //num lines of bottom fixed area
+}
+void TFT::scroll (int lines) // ie 1= scrollup 1, 479= scrolldown 1
+{
+ wr_cmd8(0x37);
+ wr_data16((topfixedareasize+lines)%scrollareasize); //num lines of top fixed area
+}
+void TFT::scrollreset()
+{
+ wr_cmd8(0x13); //normal display mode
+}
void TFT::cls (void)
{
WindowMax();
- // proto->wr_gram(_background,LCDSIZE_X*LCDSIZE_Y);
- // proto->wr_gram(0,LCDSIZE_X*LCDSIZE_Y);
- wr_gram(_background,LCDSIZE_X*LCDSIZE_Y);
+ // proto->wr_gram(_background,screensize_X*screensize_Y);
+ // proto->wr_gram(0,screensize_X*screensize_Y);
+ wr_gram(_background,screensize_X*screensize_Y);
+}
+// try to identify display controller
+void TFT::identify()
+{
+ // MIPI std read ID cmd
+ tftID=rd_reg_data32(0xBF);
+ mipistd=true;
+ // debug("ID MIPI : 0x%8X\r\n",tftID);
+ if(((tftID&0xFF)==((tftID>>8)&0xFF)) && ((tftID&0xFF)==((tftID>>16)&0xFF)))
+ {
+ mipistd=false;
+ // ILI specfic read ID cmd
+ tftID=rd_reg_data32(0xD3)>>8;
+ // debug("ID ILI : 0x%8X\r\n",tftID);
+ }
+ if(((tftID&0xFF)==((tftID>>8)&0xFF)) && ((tftID&0xFF)==((tftID>>16)&0xFF)))
+ {
+ // ILI specfic read ID cmd with ili9341 specific spi read-in enable 0xD9 cmd
+ tftID=rd_extcreg_data32(0xD3, 0xD9);
+ // debug("ID D9 extc ILI : 0x%8X\r\n",tftID);
+ }
+ if(((tftID&0xFF)==((tftID>>8)&0xFF)) && ((tftID&0xFF)==((tftID>>16)&0xFF)))
+ {
+ // ILI specfic read ID cmd with ili9486/88 specific spi read-in enable 0xFB cmd
+ tftID=rd_extcreg_data32(0xD3, 0xFB);
+ // debug("ID D9 extc ILI : 0x%8X\r\n",tftID);
+ }
+ if(((tftID&0xFF)==((tftID>>8)&0xFF)) && ((tftID&0xFF)==((tftID>>16)&0xFF))) tftID=0xDEAD;
+ if ((tftID&0xFFFF)==0x9481) scrollbugfix=1;
+ else scrollbugfix=0;
+ hw_reset(); // in case wrong cmds messed up important settings
+}
+int TFT::sizeX()
+{
+ return screensize_X;
+}
+int TFT::sizeY()
+{
+ return screensize_Y;
}
\ No newline at end of file
--- a/Display/TFT.h Mon Feb 16 01:18:29 2015 +0000
+++ b/Display/TFT.h Tue Feb 17 11:02:06 2015 +0000
@@ -85,7 +85,7 @@
*/
virtual void copy_to_lcd(){ };
- /** invert the screen
+ /** display inverted colors
*
* @param o = 0 normal, 1 invert
*/
@@ -114,6 +114,40 @@
*/
virtual void BusEnable(bool enable);
+ /** Set scroll area boundaries
+ * scroll is done in hw but only on the native vertical axis
+ * TFTs are mainly native protrait view, so horizontal scroll if rotated in landscape view
+ *
+ * @param startY boundary offset from top (or left if rotated), 0 for fullscreen scroll
+ * @param areasize size of the scroll area, 480 for fullscreen scroll of a 320x480 display
+ */
+ void setscrollarea (int startY, int areasize);
+
+ /** Scroll up(or left) the scrollarea
+ *
+ * @param lines number of lines to scroll, 1= scrollup 1, areasize-1= scrolldown 1
+ */
+ void scroll (int lines);
+
+ /** Reset the scrollarea and display un-scrolled screen
+ *
+ */
+ void scrollreset();
+
+ /** get display X size in pixels (native, orientation independent)
+ * @returns X size in pixels
+ */
+ int sizeX();
+
+ /** get display X size in pixels (native, orientation independent)
+ * @returns screen height in pixels.
+ */
+ int sizeY();
+
+ unsigned int tftID;
+
+
+
protected:
@@ -165,38 +199,44 @@
*/
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();
+ /** Read 4x8bit register data (with dummy cycle)
+ * @param reg the register to read
+ * @returns data as uint
+ *
+ */
+ virtual unsigned int rd_reg_data32(unsigned char reg);
+
+ /** Read 3x8bit ExtendedCommands register data
+ * @param reg the register to read
+ * @param SPIreadenablecmd vendor/device specific cmd to read EXTC registers
+ * @returns data as uint
+ * @note EXTC regs (0xB0 to 0xFF) are read/write registers but needs special cmd to be read in SPI mode
+ */
+ virtual unsigned int rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd);
+
/** HW reset sequence (without display init commands)
*/
void hw_reset();
+ /** Try to identify display ID
+ * @note support ILI9341,94xx, MIPI standard. May be be overridden in Init class for other specific IC
+ */
+ virtual void identify();
+
unsigned int scrollbugfix;
bool mipistd;
private:
Protocols* proto;
- const int LCDSIZE_X;
- const int LCDSIZE_Y;
- // const int LCDPAGES;
- // const int IC_X_SEGS;
- // const int IC_Y_COMS;
- // const int IC_PAGES;
-
- // int page_offset;
- // int col_offset;
+ const int screensize_X;
+ const int screensize_Y;
// pixel location
int cur_x;
int cur_y;
@@ -206,7 +246,8 @@
int win_y1;
int win_y2;
int orientation;
- unsigned int tftID;
+ int topfixedareasize;
+ int scrollareasize;
bool useNOP;
};
--- a/Inits/ILI9341.cpp Mon Feb 16 01:18:29 2015 +0000
+++ b/Inits/ILI9341.cpp Tue Feb 17 11:02:06 2015 +0000
@@ -20,8 +20,8 @@
{
hw_reset();
BusEnable(true);
+ identify(); // will collect tftID and set mipistd flag
init();
- mipistd=false;
set_orientation(0);
cls();
locate(0,0);
@@ -31,8 +31,8 @@
{
hw_reset(); //TFT class forwards to Protocol class
BusEnable(true); //TFT class forwards to Protocol class
+ identify(); // will collect tftID and set mipistd flag
init(); // per display custom init cmd sequence, implemented here
- mipistd=false;
set_orientation(0); //TFT class does for MIPI standard and some ILIxxx
cls();
locate(0,0);
--- a/Inits/ILI9486.cpp Mon Feb 16 01:18:29 2015 +0000
+++ b/Inits/ILI9486.cpp Tue Feb 17 11:02:06 2015 +0000
@@ -19,9 +19,8 @@
{
hw_reset();
BusEnable(true);
+ identify(); // will collect tftID and set mipistd flag
init();
- mipistd=false;
- scrollbugfix=1; // when scrolling 1 line, the last line disappears, set to 1 to fix it
set_orientation(0);
cls();
locate(0,0);
@@ -31,9 +30,8 @@
{
hw_reset(); //TFT class forwards to Protocol class
BusEnable(true); //TFT class forwards to Protocol class
+ identify(); // will collect tftID and set mipistd flag
init(); // per display custom init cmd sequence, implemented here
- mipistd=false;
- scrollbugfix=1; // when scrolling 1 line, the last line disappears, set to 1 to fix it
set_orientation(0); //TFT class does for MIPI standard and some ILIxxx
cls();
locate(0,0);
--- a/Inits/TFT_MIPI.cpp Mon Feb 16 01:18:29 2015 +0000
+++ b/Inits/TFT_MIPI.cpp Tue Feb 17 11:02:06 2015 +0000
@@ -19,8 +19,9 @@
{
hw_reset();
BusEnable(true);
+ identify(); // will collect tftID, set mipistd flag
init();
- mipistd=true;
+// scrollbugfix=1; // when scrolling 1 line, the last line disappears, set to 1 to fix it, for ili9481 is set automatically in identify()
set_orientation(0);
cls();
locate(0,0);
@@ -30,8 +31,9 @@
{
hw_reset(); //TFT class forwards to Protocol class
BusEnable(true); //TFT class forwards to Protocol class
+ identify(); // will collect tftID and set mipistd flag
init(); // per display custom init cmd sequence, implemented here
- mipistd=true;
+ // scrollbugfix=1; // when scrolling 1 line, the last line disappears, set to 1 to fix it, for ili9481 is set automatically in identify()
set_orientation(0); //TFT class does for MIPI standard and some ILIxxx
cls();
locate(0,0);
--- a/Protocols/PAR16.cpp Mon Feb 16 01:18:29 2015 +0000
+++ b/Protocols/PAR16.cpp Tue Feb 17 11:02:06 2015 +0000
@@ -150,11 +150,36 @@
_CS = 1;
#endif
}
-unsigned int PAR16::rd_data32_wdummy()
+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;
+}
+unsigned int PAR16::rd_reg_data32(unsigned char reg)
+{
+#ifdef USE_CS
+ _CS = 0;
+#endif
+ wr_cmd8(reg);
unsigned int r=0;
_DC = 1; // 1=data
_port.input();
@@ -193,29 +218,10 @@
_port.output();
return r;
}
-unsigned short PAR16::rd_gram()
+// in Par mode EXTC regs (0xB0-0xFF) can be directly read
+unsigned int PAR16::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd)
{
-#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;
+ return rd_reg_data32(reg);
}
void PAR16::hw_reset()
{
--- a/Protocols/PAR16.h Mon Feb 16 01:18:29 2015 +0000
+++ b/Protocols/PAR16.h Tue Feb 17 11:02:06 2015 +0000
@@ -75,19 +75,26 @@
*/
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();
+ /** Read 4x8bit register data (with dummy cycle)
+ * @param reg the register to read
+ * @returns data as uint
+ *
+ */
+ virtual unsigned int rd_reg_data32(unsigned char reg);
+
+ /** Read 3x8bit ExtendedCommands register data
+ * @param reg the register to read
+ * @returns data as uint
+ * @note EXTC regs (0xB0 to 0xFF) are read/write registers, for Parallel mode directly accessible in both directions
+ */
+ virtual unsigned int rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd);
+
/** HW reset sequence (without display init commands)
*/
virtual void hw_reset();
--- a/Protocols/PAR8.cpp Mon Feb 16 01:18:29 2015 +0000
+++ b/Protocols/PAR8.cpp Tue Feb 17 11:02:06 2015 +0000
@@ -174,11 +174,42 @@
_CS = 1;
#endif
}
-unsigned int PAR8::rd_data32_wdummy()
+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;
+}
+unsigned int PAR8::rd_reg_data32(unsigned char reg)
+{
+#ifdef USE_CS
+ _CS = 0;
+#endif
+ wr_cmd8(reg);
unsigned int r=0;
_DC = 1; // 1=data
_port.input();
@@ -217,35 +248,10 @@
_port.output();
return r;
}
-unsigned short PAR8::rd_gram()
+// in Par mode EXTC regs (0xB0-0xFF) can be directly read
+unsigned int PAR8::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd)
{
-#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;
+ return rd_reg_data32(reg);
}
void PAR8::hw_reset()
{
--- a/Protocols/PAR8.h Mon Feb 16 01:18:29 2015 +0000
+++ b/Protocols/PAR8.h Tue Feb 17 11:02:06 2015 +0000
@@ -75,19 +75,26 @@
*/
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();
+ /** Read 4x8bit register data (with dummy cycle)
+ * @param reg the register to read
+ * @returns data as uint
+ *
+ */
+ virtual unsigned int rd_reg_data32(unsigned char reg);
+
+ /** Read 3x8bit ExtendedCommands register data
+ * @param reg the register to read
+ * @returns data as uint
+ * @note EXTC regs (0xB0 to 0xFF) are read/write registers, for Parallel mode directly accessible in both directions
+ */
+ virtual unsigned int rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd);
+
/** HW reset sequence (without display init commands)
*/
virtual void hw_reset();
--- a/Protocols/Protocols.h Mon Feb 16 01:18:29 2015 +0000
+++ b/Protocols/Protocols.h Tue Feb 17 11:02:06 2015 +0000
@@ -82,19 +82,27 @@
*/
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;
+ /** Read 4x8bit register data (with dummy cycle)
+ * @param reg the register to read
+ * @returns data as uint
+ *
+ */
+ virtual unsigned int rd_reg_data32(unsigned char reg) = 0;
+
+ /** Read 3x8bit ExtendedCommands register data
+ * @param reg the register to read
+ * @param SPIreadenablecmd vendor/device specific cmd to read EXTC registers
+ * @returns data as uint
+ * @note EXTC regs (0xB0 to 0xFF) are read/write registers but needs special cmd to be read in SPI mode
+ */
+ virtual unsigned int rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd) = 0;
+
/** HW reset sequence (without display init commands)
*/
virtual void hw_reset() = 0;
--- a/Protocols/SPI16.cpp Mon Feb 16 01:18:29 2015 +0000
+++ b/Protocols/SPI16.cpp Tue Feb 17 11:02:06 2015 +0000
@@ -121,26 +121,6 @@
_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
@@ -160,6 +140,45 @@
r = RGB18to16((r&0xFC0000)>>16, (r&0xFC00)>>8, r&0xFC);// 18bit pixel, rrrrrr00_gggggg00_bbbbbb00, converted to 16bit
return (unsigned short)r;
}
+unsigned int SPI16::rd_reg_data32(unsigned char reg)
+{
+#ifdef USE_CS
+ _CS = 0;
+#endif
+ wr_cmd8(reg);
+ 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 int SPI16::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd)
+{
+ unsigned int r=0;
+ for(int regparam=1; regparam<4; regparam++) // when reading EXTC regs, first parameter is always dummy, so start with 1
+ {
+ wr_cmd8(SPIreadenablecmd); // spi-in enable cmd, 0xD9 (ili9341) or 0xFB (ili9488) or don't know
+ wr_data8(0xF0|regparam); // in low nibble specify which reg parameter we want
+ wr_cmd8(reg); // now send cmd (select register we want to read)
+ _DC.write(1); // 1=data
+ r <<= 8;
+ r |= (_spi.write(0) >> 8);
+ }
+_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;
+}
void SPI16::hw_reset()
{
wait_ms(15);
--- a/Protocols/SPI16.h Mon Feb 16 01:18:29 2015 +0000
+++ b/Protocols/SPI16.h Tue Feb 17 11:02:06 2015 +0000
@@ -77,19 +77,27 @@
*/
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();
+ /** Read 4x8bit register data (with dummy cycle)
+ * @param reg the register to read
+ * @returns data as uint
+ *
+ */
+ virtual unsigned int rd_reg_data32(unsigned char reg);
+
+ /** Read 3x8bit ExtendedCommands register data
+ * @param reg the register to read
+ * @param SPIreadenablecmd vendor/device specific cmd to read EXTC registers
+ * @returns data as uint
+ * @note EXTC regs (0xB0 to 0xFF) are read/write registers but needs special cmd to be read in SPI mode
+ */
+ virtual unsigned int rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd);
+
/** HW reset sequence (without display init commands)
*/
virtual void hw_reset();
--- a/Protocols/SPI8.cpp Mon Feb 16 01:18:29 2015 +0000
+++ b/Protocols/SPI8.cpp Tue Feb 17 11:02:06 2015 +0000
@@ -135,30 +135,6 @@
_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
@@ -181,6 +157,50 @@
r = RGB18to16((r&0xFC0000)>>16, (r&0xFC00)>>8, r&0xFC);// 18bit pixel, rrrrrr00_gggggg00_bbbbbb00, converted to 16bit
return (unsigned short)r;
}
+unsigned int SPI8::rd_reg_data32(unsigned char reg)
+{
+#ifdef USE_CS
+ _CS = 0;
+#endif
+ wr_cmd8(reg);
+ 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 int SPI8::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd)
+{
+ unsigned int r=0;
+ for(int regparam=1; regparam<4; regparam++) // when reading EXTC regs, first parameter is always dummy, so start with 1
+ {
+ wr_cmd8(SPIreadenablecmd); // spi-in enable cmd, 0xD9 (ili9341) or 0xFB (ili9488) or don't know
+ wr_data8(0xF0|regparam); // in low nibble specify which reg parameter we want
+ wr_cmd8(reg); // now send cmd (select register we want to read)
+ _DC.write(1); // 1=data
+ r <<= 8;
+ r |= _spi.write(0);
+ // r = _spi.write(0) >> 8; for 16bit
+ }
+_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;
+}
void SPI8::hw_reset()
{
wait_ms(15);
--- a/Protocols/SPI8.h Mon Feb 16 01:18:29 2015 +0000
+++ b/Protocols/SPI8.h Tue Feb 17 11:02:06 2015 +0000
@@ -74,19 +74,27 @@
*/
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();
+ /** Read 4x8bit register data (with dummy cycle)
+ * @param reg the register to read
+ * @returns data as uint
+ *
+ */
+ virtual unsigned int rd_reg_data32(unsigned char reg);
+
+ /** Read 3x8bit ExtendedCommands register data
+ * @param reg the register to read
+ * @param SPIreadenablecmd vendor/device specific cmd to read EXTC registers
+ * @returns data as uint
+ * @note EXTC regs (0xB0 to 0xFF) are read/write registers but needs special cmd to be read in SPI mode
+ */
+ virtual unsigned int rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd);
+
/** HW reset sequence (without display init commands)
*/
virtual void hw_reset();
