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

Files at this revision

API Documentation at this revision

Comitter:
rpocc
Date:
Mon Jan 11 09:35:06 2016 +0000
Parent:
27:26491d710e72
Commit message:
All changes are valid for ssd1289; Overloaded constructors added;; _fast_fill_16 protected methods are added for fast rectangle fill;; DrawHLine and DrawVLine are now Public.; Changes made by Dmitry Shtatnov

Changed in this revision

lcd_base.h Show annotated file Show diff for this revision Revisions of this file
ssd1289.cpp Show annotated file Show diff for this revision Revisions of this file
ssd1289.h Show annotated file Show diff for this revision Revisions of this file
--- a/lcd_base.h	Mon Jul 22 01:48:06 2013 +0000
+++ b/lcd_base.h	Mon Jan 11 09:35:06 2016 +0000
@@ -285,12 +285,12 @@
     /** Gets the font width.
      *  \return The current font width.
      */
-    uint8_t GetFontWidth( void );
+    virtual uint8_t GetFontWidth( void );
     
     /** Gets the font height.
      *  \return The current font height.
      */
-    uint8_t GetFontHeight( void );
+    virtual uint8_t GetFontHeight( void );
     
     /** Fills the whole screen with a single color.
      * \param color The color to be used. The value must be in RGB-565 format.
@@ -432,6 +432,45 @@
      * \param roy
      */
     virtual void DrawBitmap( unsigned short x, unsigned short y, const bitmap_t* img, unsigned short deg, unsigned short rox, unsigned short roy );
+
+    /** Draws a horizontal line.
+     *
+     * This is a utility function to draw horizontal-only lines
+     * for reduced code complexity and faster execution.
+     *
+     * \param x X coordinate of the starting point of the line.
+     * \param y Y coordinate of the starting point of the line.
+     * \param len Length of the line.
+     * \param color The color to use to draw the line. By default the global foreground color is used ( -2 ),
+     *              -1 switches to the default background color, or any custom color can be used.
+     */
+    virtual void DrawHLine( unsigned short x, unsigned short y, unsigned short len, int color = -2 );
+    
+    /** Draws a vertical line.
+     *
+     * This is a utility function to draw vertical-only lines
+     * for reduced code complexity and faster execution.
+     *
+     * \param x X coordinate of the starting point of the line.
+     * \param y Y coordinate of the starting point of the line.
+     * \param len Height of the line.
+     * \param color The color to use to draw the line. By default the global foreground color is used ( -2 ),
+     *              -1 switches to the default background color, or any custom color can be used.
+     */
+    virtual void DrawVLine( unsigned short x, unsigned short y, unsigned short len, int color = -2 );
+
+    /** Prints a character at the given position and using the given color.
+     *
+     * \param c The character.
+     * \param x X coordinate of the character position.
+     * \param y Y coordinate of the character position.
+     * \param fgColor Foreground color for drawing. By default the global foreground color is used ( -2 ),
+     *                -1 switches to the default background color, or any custom color can be used.
+     * \param bgColor Background color for drawing. By default the global background color is used ( -1 ),
+     *                -2 switches to the default foreground color, or any custom color can be used.
+     */
+    virtual void PrintChar( char c, unsigned short x, unsigned short y, int fgColor = -2, int bgColor = -1 );
+    
     
 protected:
     /** Creates an instance of the class.
@@ -516,43 +555,6 @@
      */
     virtual void SetPixelColor( unsigned int color, colordepth_t mode = RGB24 ) = 0;
     
-    /** Draws a horizontal line.
-     *
-     * This is a utility function to draw horizontal-only lines
-     * for reduced code complexity and faster execution.
-     *
-     * \param x X coordinate of the starting point of the line.
-     * \param y Y coordinate of the starting point of the line.
-     * \param len Length of the line.
-     * \param color The color to use to draw the line. By default the global foreground color is used ( -2 ),
-     *              -1 switches to the default background color, or any custom color can be used.
-     */
-    virtual void DrawHLine( unsigned short x, unsigned short y, unsigned short len, int color = -2 );
-    
-    /** Draws a vertical line.
-     *
-     * This is a utility function to draw vertical-only lines
-     * for reduced code complexity and faster execution.
-     *
-     * \param x X coordinate of the starting point of the line.
-     * \param y Y coordinate of the starting point of the line.
-     * \param len Height of the line.
-     * \param color The color to use to draw the line. By default the global foreground color is used ( -2 ),
-     *              -1 switches to the default background color, or any custom color can be used.
-     */
-    virtual void DrawVLine( unsigned short x, unsigned short y, unsigned short len, int color = -2 );
-    
-    /** Prints a character at the given position and using the given color.
-     *
-     * \param c The character.
-     * \param x X coordinate of the character position.
-     * \param y Y coordinate of the character position.
-     * \param fgColor Foreground color for drawing. By default the global foreground color is used ( -2 ),
-     *                -1 switches to the default background color, or any custom color can be used.
-     * \param bgColor Background color for drawing. By default the global background color is used ( -1 ),
-     *                -2 switches to the default foreground color, or any custom color can be used.
-     */
-    virtual void PrintChar( char c, unsigned short x, unsigned short y, int fgColor = -2, int bgColor = -1 );
     
     /** Prints a character at the given position and using the given color and with the given rotation.
      *
--- 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 )
--- a/ssd1289.h	Mon Jul 22 01:48:06 2013 +0000
+++ b/ssd1289.h	Mon Jan 11 09:35:06 2016 +0000
@@ -8,10 +8,14 @@
  * This library is based on the Arduino/chipKIT UTFT library by Henning
  * Karlsen, http://henningkarlsen.com/electronics/library.php?id=52
  *
+ * Optimized fast version for SSD1289 by Dmitry Shtatnov
+ *
  * Copyright (C)2010-2012 Henning Karlsen. All right reserved.
  *
  * Copyright (C)2012 Todor Todorov.
  *
+ * Copyright (C)2016 Dmitry Shtatnov
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
@@ -55,10 +59,20 @@
  * // include the library, this will also pull in the header for the provided fonts
  * #include "ssd1289.h"
  * 
- * // prepare the data bus for writing commands and pixel data
+ * // prepare the data bus for writing commands and pixel data (LSB..MSB)
  * BusOut dataBus( p30, p29, p28, p27, p26, p25, p24, p23, p22, p21, p20, p19, p18, p17, p16, p15 ); // 16 pins
  * // create the lcd instance
  * SSD1289_LCD lcd( p14, p13, p12, p11, &dataBus ); // control pins and data bus
+ * // You can also prepare a PortOut for faster operation:
+ * // PortOut dataPort(PortC, 0xFFFF); // 16 pins
+ * // SSD1289_LCD lcd( p14, p13, p12, p11, &dataPort ); // control pins and data bus
+ * //
+ * // Or, you can use separated port, which is usefull with some platforms such as ST Nucleo F401RE,
+ * // having no ports with all 16 pins available for output. (by default)
+ * // PortOut dataPortA(PortA, 0xFF00); // 16 pins
+ * // PortOut dataPortC(PortC, 0x00FF); // 16 pins
+ * // SSD1289_LCD lcd( p14, p13, p12, p11, &dataPortA, &dataPortC ); // control pins and data bus
+ 
  *
  * int main()
  * {
@@ -66,7 +80,7 @@
  *     //                      foreground to white color.
  *     lcd.Initialize();
  *     // set current font to the smallest 8x12 pixels font.
- *     lcd.SetFont( Font8x12 );
+ *     lcd.SetFont( &TerminusFont );
  *     // print something on the screen
  *     lcd.Print( "Hello, World!", CENTER, 25 ); // align text to center horizontally and use starndard colors
  *
@@ -95,6 +109,39 @@
      * \param defaultBacklightLevel If using PWM to control backlight, this would be the default brightness in percent after LCD initialization.
      */
     SSD1289_LCD( PinName CS, PinName RESET, PinName RS, PinName WR, BusOut* DATA_PORT, PinName BL = NC, PinName RD = NC, backlight_t blType = Constant, float defaultBackLightLevel = 1.0 );
+
+    /** Creates a new instance of the class.
+     *
+     * \param CS Pin for the ChipSelect signal.
+     * \param RESET Pin for the RESET line.
+     * \param RS Pin for the RS signal.
+     * \param WR Pin for the WR signal.
+     * \param FAST_DATA_PORT_H High Byte Address of the data port for transfer of commands and pixel data. Should have 0xFF00 mask
+     * \param FAST_DATA_PORT_L Low Byte Address of the data port for transfer of commands and pixel data. Should have 0x00FF mask
+     * \param BL Pin for controlling the backlight. By default not used.
+     * \param RD Pin for the RD signal. This line is not needed by the driver, so if you would like to
+     *       use the pin on the mbed for something else, just pull-up the respective pin on the LCD high,
+     *       and do not assign a value to this parameter when creating the controller instance.
+     * \param blType The backlight type, the default is to utilize the pin - if supplied - as a simple on/off switch
+     * \param defaultBacklightLevel If using PWM to control backlight, this would be the default brightness in percent after LCD initialization.
+     */
+    SSD1289_LCD( PinName CS, PinName RESET, PinName RS, PinName WR, PortOut* FAST_DATA_PORT_H, PortOut* FAST_DATA_PORT_L, PinName BL = NC, PinName RD = NC, backlight_t blType = Constant, float defaultBackLightLevel = 1.0 );
+
+    /** Creates a new instance of the class.
+     *
+     * \param CS Pin for the ChipSelect signal.
+     * \param RESET Pin for the RESET line.
+     * \param RS Pin for the RS signal.
+     * \param WR Pin for the WR signal.
+     * \param FAST_DATA_PORT Address of the data port for transfer of commands and pixel data.
+     * \param BL Pin for controlling the backlight. By default not used.
+     * \param RD Pin for the RD signal. This line is not needed by the driver, so if you would like to
+     *       use the pin on the mbed for something else, just pull-up the respective pin on the LCD high,
+     *       and do not assign a value to this parameter when creating the controller instance.
+     * \param blType The backlight type, the default is to utilize the pin - if supplied - as a simple on/off switch
+     * \param defaultBacklightLevel If using PWM to control backlight, this would be the default brightness in percent after LCD initialization.
+     */
+    SSD1289_LCD( PinName CS, PinName RESET, PinName RS, PinName WR, PortOut* FAST_DATA_PORT, PinName BL = NC, PinName RD = NC, backlight_t blType = Constant, float defaultBackLightLevel = 1.0 );
     
     /** Initialize display.
      *
@@ -134,6 +181,14 @@
      */
     virtual void WakeUp( void );
     
+    virtual void FillScreen( int color );
+
+    virtual void FillRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color );
+
+    virtual void DrawVLine( unsigned short x, unsigned short y, unsigned short len, int color = -2);
+
+    virtual void DrawHLine( unsigned short x, unsigned short y, unsigned short len, int color = -2);
+
 protected:
     /** Sends a command to the display.
      *
@@ -151,6 +206,8 @@
      */
     virtual void WriteData( unsigned short data );
     
+    virtual void _fast_fill_16(int color, long pix);
+    
     /** Assigns a chunk of the display memory to receive data.
      *
      * When data is sent to the display after this function completes, the opertion will
@@ -183,6 +240,9 @@
     BusOut*     _lcd_port;
     DigitalOut* _lcd_pin_bl;
     DigitalOut* _lcd_pin_rd;
+    PortOut* _hp;
+    PortOut* _lp;
+    bool    _use_fast_port, _use_separate_port;
 };
 
 #ifdef __cplusplus