A modifiedversion of TFTLCD by Todor Todorov with ultra-fast operation for SSD1289 controller. TODO: speed-up fonts, add my own fonts Can work out-of-the-box with ST Nucleo F401RE

Dependents:   TFT_320QVT_Window_Drag_Demo TFT_320QVT_HelloWorld

Fork of TFTLCD by Todor Todorov

Revision:
28:2f24de90cb46
Parent:
22:4c169297f374
diff -r 26491d710e72 -r 2f24de90cb46 ssd1289.cpp
--- a/ssd1289.cpp	Mon Jul 22 01:48:06 2013 +0000
+++ b/ssd1289.cpp	Mon Jan 11 09:35:06 2016 +0000
@@ -26,6 +26,30 @@
     : LCD( 240, 320, CS, RS, RESET, BL, blType, defaultBackLightLevel ), _lcd_pin_wr( WR )
 {
     _lcd_port = DATA_PORT;
+    _use_fast_port = false;
+    _use_separate_port = false;
+    if ( RD != NC ) _lcd_pin_rd = new DigitalOut( RD );
+    else _lcd_pin_rd = 0;
+}
+
+SSD1289_LCD::SSD1289_LCD( PinName CS, PinName RESET, PinName RS, PinName WR, PortOut* FAST_DATA_PORT, PinName BL, PinName RD, backlight_t blType, float defaultBackLightLevel )
+    : LCD( 240, 320, CS, RS, RESET, BL, blType, defaultBackLightLevel ), _lcd_pin_wr( WR )
+{
+    if ( RD != NC ) _lcd_pin_rd = new DigitalOut( RD );
+    else _lcd_pin_rd = 0;
+    _lp = FAST_DATA_PORT;
+    _use_fast_port = true;
+    _use_separate_port = false;
+
+}
+
+SSD1289_LCD::SSD1289_LCD( PinName CS, PinName RESET, PinName RS, PinName WR, PortOut* FAST_DATA_PORT_H, PortOut* FAST_DATA_PORT_L, PinName BL, PinName RD, backlight_t blType, float defaultBackLightLevel )
+    : LCD( 240, 320, CS, RS, RESET, BL, blType, defaultBackLightLevel ), _lcd_pin_wr( WR )
+{
+    _hp = FAST_DATA_PORT_H;
+    _lp = FAST_DATA_PORT_L;
+    _use_fast_port = true;
+    _use_separate_port = true;
     if ( RD != NC ) _lcd_pin_rd = new DigitalOut( RD );
     else _lcd_pin_rd = 0;
 }
@@ -209,17 +233,136 @@
 void SSD1289_LCD::WriteCmd( unsigned short cmd )
 {
     _lcd_pin_rs = LOW;
-    _lcd_port->write( cmd );
+    if(_use_fast_port)
+    {
+        _lp->write(cmd);
+        if(_use_separate_port)
+        {
+            _hp->write(cmd);
+        }
+    }
+    else
+    {
+        _lcd_port->write( cmd );
+    }
+    
     pulseLow( _lcd_pin_wr );
 }
 
 void SSD1289_LCD::WriteData( unsigned short data )
 {
     _lcd_pin_rs = HIGH;
-    _lcd_port->write( data );
+    if(_use_fast_port)
+    {
+        _lp->write(data);
+        if(_use_separate_port)
+        {
+            _hp->write(data);
+        }
+    }
+    else
+    {
+        _lcd_port->write( data );
+    }
+
     pulseLow( _lcd_pin_wr );
 }
 
+void SSD1289_LCD::_fast_fill_16(int color, long pix)
+{
+    long blocks;
+    uint16_t i;
+    unsigned char r, g, b;
+    unsigned short clr;
+    r = ( color >> 16 ) & 0xF8;
+    g = ( color >> 8 ) & 0xFC;
+    b = color & 0xF8;
+    clr = ( ( r | ( g >> 5 ) ) << 8 ) | ( ( g << 3 ) | ( b >> 3 ) );
+
+    if(_use_fast_port)
+    {
+        _lp->write(clr);
+        if(_use_separate_port)
+        {
+            _hp->write(clr);
+        }
+    }
+    else
+    {
+        _lcd_port->write(clr);
+    }
+    blocks = pix/16;
+    for (i=0; i<blocks; i++)
+    {
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    pulseLow( _lcd_pin_wr );
+    }
+    if ((pix % 16) != 0)
+        for (i=0; i<(pix % 16)+1; i++)
+        {     
+            pulseLow( _lcd_pin_wr );
+        }
+}
+
+void SSD1289_LCD::FillScreen( int color )
+{
+
+    Activate();
+    ClearXY();
+    _lcd_pin_rs = HIGH;
+    _fast_fill_16(color, _disp_width*_disp_height);
+    Deactivate();
+}
+
+void SSD1289_LCD::FillRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
+{
+    if ( x1 > x2 ) swap( ushort, x1, x2 );
+    if ( y1 > y2 ) swap( ushort, y1, y2 );
+
+    Activate();
+    SetXY(x1, y1, x2, y2);
+    _lcd_pin_rs = HIGH;
+    _fast_fill_16(color, (x2-x1+1)*(y2-y1+1));
+    Deactivate();
+}
+
+void SSD1289_LCD::DrawHLine( unsigned short x, unsigned short y, unsigned short len, int color )
+{
+    unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
+    
+    Activate();
+    SetXY( x, y, x + len-1, y );
+    _lcd_pin_rs = HIGH;
+    _fast_fill_16(usedColor, len);
+    Deactivate();
+}
+
+void SSD1289_LCD::DrawVLine( unsigned short x, unsigned short y, unsigned short len, int color )
+{
+    unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
+    
+    Activate();
+    SetXY( x, y, x, y + len-1 );
+    _lcd_pin_rs = HIGH;
+    _fast_fill_16(usedColor, len);
+    Deactivate();
+}
+
+
 void SSD1289_LCD::SetXY( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2 )
 {
     if ( _orientation == PORTRAIT || _orientation == PORTRAIT_REV )