Fork of SSD1289 lib for Landtiger board

Revision:
1:f4f77e6729cd
Parent:
0:d7202c9fc5db
Child:
2:799c4fb113c5
--- a/ssd1289.cpp	Wed Nov 21 05:13:24 2012 +0000
+++ b/ssd1289.cpp	Wed Nov 21 23:11:20 2012 +0000
@@ -1,11 +1,14 @@
 #include "ssd1289.h"
 
-#define pulseLow( pin )         pin = 0; pin = 1
-#define pulseHigh( pin )        pin = 1; pin = 0
+#define LOW                     0
+#define HIGH                    1
+#define pulseLow( pin )         pin = LOW; pin = HIGH
+#define pulseHigh( pin )        pin = HIGH; pin = LOW
+#define swap( type, a, b )      { type tmp = ( a ); ( a ) = ( b ); ( b ) = tmp; }
 
-extern unsigned char Font8x12[];
-extern unsigned char Font16x16[];
-extern unsigned char Font7Segment[];
+#ifndef ushort
+typedef unsigned short ushort;
+#endif
 
 SSD1289::SSD1289( PinName CS_PIN, PinName RESET_PIN, PinName RS_PIN, PinName WR_PIN, PinName RD_PIN, BusOut* DATA_PORT )
     : _lcd_pin_cs( CS_PIN ), _lcd_pin_reset( RESET_PIN ), _lcd_pin_rs( RS_PIN ), _lcd_pin_wr( WR_PIN ), _lcd_pin_rd( RD_PIN )
@@ -13,27 +16,591 @@
     _lcd_port = DATA_PORT;
 }
 
+/*
+
+void SSD1289::PrintNumI( long num, int x, int y )
+{
+    char buf[ 25 ];
+    char st[ 27 ];
+    bool neg = false;
+    int c = 0;
+
+    if ( num == 0 )
+    {
+        st[ 0 ] = 48;
+        st[ 1 ] = 0;
+    }
+    else
+    {
+        if ( num < 0 )
+        {
+            neg = true;
+            num = -num;
+        }
+
+        while ( num > 0 )
+        {
+            buf[ c ] = 48 + ( num % 10 );
+            c++;
+            num = ( num - ( num % 10 ) ) / 10;
+        }
+        buf[ c ] = 0;
+
+        if ( neg )
+        {
+            st[ 0 ] = 45;
+        }
+
+        for ( int i = 0; i < c; i++ )
+        {
+            st[ i + neg ] = buf[ c - i - 1 ];
+        }
+        st[ c + neg ] = 0;
+    }
+
+    Print( st, x, y );
+}
+
+void SSD1289::PrintNumF( double num, uint8_t dec, int x, int y, char divider )
+{
+    char buf[ 25 ];
+    char st[ 27 ];
+    bool neg = false;
+    int c = 0;
+    int c2, mult;
+    unsigned long inum;
+
+    if ( num == 0 )
+    {
+        st[ 0 ] = 48;
+        st[ 1 ] = divider;
+        for ( int i = 0; i < dec; i++ )
+            st[ 2 + i ] = 48;
+        st[ 2 + dec ] = 0;
+    }
+    else
+    {
+        if ( num < 0 )
+        {
+            neg = true;
+            num = -num;
+        }
+
+        if ( dec < 1 )
+            dec = 1;
+        if ( dec > 5 )
+            dec = 5;
+
+        mult = 1;
+        for ( int j = 0; j < dec; j++ )
+            mult = mult * 10;
+        inum = long( num * mult + 0.5 );
+
+        while ( inum > 0 )
+        {
+            buf[ c ] = 48 + ( inum % 10 );
+            c++;
+            inum = ( inum - ( inum % 10 ) ) / 10;
+        }
+        if ( ( num < 1 ) and ( num > 0 ) )
+        {
+            buf[ c ] = 48;
+            c++;
+        }
+        buf[ c ] = 0;
+
+        if ( neg )
+        {
+            st[ 0 ] = 45;
+        }
+
+        c2 = neg;
+        for ( int i = 0; i < c; i++ )
+        {
+            st[ c2 ] = buf[ c - i - 1 ];
+            c2++;
+            if ( ( c - ( c2 - neg ) ) == dec )
+            {
+                st[ c2 ] = divider;
+                c2++;
+            }
+        }
+        st[ c2 ] = 0;
+    }
+
+    Print( st, x, y );
+}
+
+*/
+
 void SSD1289::Initialize( orientation_t orientation )
 {
     _orientation = orientation;
+    SetForeground();
+    SetBackground();
+    _font.font = 0;
+    
+    _lcd_pin_reset = HIGH;
+    wait_ms( 5 );
+    _lcd_pin_reset = LOW;
+    wait_ms( 15 );
+    _lcd_pin_reset = HIGH;
+    _lcd_pin_cs = HIGH;
+    _lcd_pin_rd = HIGH;
+    _lcd_pin_wr = HIGH;
+    wait_ms( 15 );
+    
+    
+    writeCmdData( 0x00, 0x0001 ); wait_ms( 1 );
+    writeCmdData( 0x03, 0xA8A4 ); wait_ms( 1 );
+    writeCmdData( 0x0C, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x0D, 0x080C ); wait_ms( 1 );
+    writeCmdData( 0x0E, 0x2B00 ); wait_ms( 1 );
+    writeCmdData( 0x1E, 0x00B7 ); wait_ms( 1 );
+    writeCmdData( 0x01, 0x2B3F ); wait_ms( 1 );
+    writeCmdData( 0x02, 0x0600 ); wait_ms( 1 );
+    writeCmdData( 0x10, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x11, 0x6070 ); wait_ms( 1 );
+    writeCmdData( 0x05, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x06, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x16, 0xEF1C ); wait_ms( 1 );
+    writeCmdData( 0x17, 0x0003 ); wait_ms( 1 );
+    writeCmdData( 0x07, 0x0233 ); wait_ms( 1 );
+    writeCmdData( 0x0B, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x0F, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x41, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x42, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x48, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x49, 0x013F ); wait_ms( 1 );
+    writeCmdData( 0x4A, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x4B, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x44, 0xEF00 ); wait_ms( 1 );
+    writeCmdData( 0x45, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x46, 0x013F ); wait_ms( 1 );
+    writeCmdData( 0x30, 0x0707 ); wait_ms( 1 );
+    writeCmdData( 0x31, 0x0204 ); wait_ms( 1 );
+    writeCmdData( 0x32, 0x0204 ); wait_ms( 1 );
+    writeCmdData( 0x33, 0x0502 ); wait_ms( 1 );
+    writeCmdData( 0x34, 0x0507 ); wait_ms( 1 );
+    writeCmdData( 0x35, 0x0204 ); wait_ms( 1 );
+    writeCmdData( 0x36, 0x0204 ); wait_ms( 1 );
+    writeCmdData( 0x37, 0x0502 ); wait_ms( 1 );
+    writeCmdData( 0x3A, 0x0302 ); wait_ms( 1 );
+    writeCmdData( 0x3B, 0x0302 ); wait_ms( 1 );
+    writeCmdData( 0x23, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x24, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x25, 0x8000 ); wait_ms( 1 );
+    writeCmdData( 0x4f, 0x0000 ); wait_ms( 1 );
+    writeCmdData( 0x4e, 0x0000 ); wait_ms( 1 );
+    writeCmd( 0x22 );
+}
+
+void SSD1289::SetForeground( unsigned short color )
+{
+    _foreground = color;
+}
+
+void SSD1289::SetBackground( unsigned short color )
+{
+    _background = color;
+}
+
+void SSD1289::SetFont( const char *font )
+{
+    _font.font     = font;
+    _font.width    = font[ 0 ];
+    _font.height   = font[ 1 ];
+    _font.offset   = font[ 2 ];
+    _font.numchars = font[ 3 ];
+}
+
+void SSD1289::FillScreen( int color )
+{
+    unsigned short rgb = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color;
+    _lcd_pin_cs = LOW;
+    clearXY();
+    _lcd_pin_rs = HIGH;
+    for ( int i = 0; i < ( ( _disp_width + 1 ) * ( _disp_height + 1 ) ); i++ )
+        writeData( rgb );
+    _lcd_pin_cs = HIGH;
+}
+
+void SSD1289::ClearScreen( void )
+{
+    FillScreen( -1 );
+}
+
+void SSD1289::DrawPixel( unsigned short x, unsigned short y, int color )
+{
+    _lcd_pin_cs = LOW;
+    setXY( x, y, x, y );
+    writeData( color == -1 ? _background :
+                    color == -2 ? _foreground : color );
+    _lcd_pin_cs = HIGH;
+    clearXY();
+}
+
+void SSD1289::DrawLine( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
+{
+    
+    double delta, tx, ty;
+
+    if ( ( ( x2 - x1 ) < 0 ) )
+    {
+        swap( ushort, x1, x2 )
+        swap( ushort, y1, y2 )
+    }
+    if ( ( ( y2 - y1 ) < 0 ) )
+    {
+        swap( ushort, x1, x2 )
+        swap( ushort, y1, y2 )
+    }
+
+    if ( y1 == y2 )
+    {
+        if ( x1 > x2 )
+            swap( ushort, x1, x2 )
+        drawHLine( x1, y1, x2 - x1, color );
+    }
+    else if ( x1 == x2 )
+    {
+        if ( y1 > y2 )
+            swap( ushort, y1, y2 )
+        drawVLine( x1, y1, y2 - y1, color );
+    }
+    else if ( abs( x2 - x1 ) > abs( y2 - y1 ) )
+    {
+        unsigned short usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color;
+        _lcd_pin_cs = LOW;
+        delta = ( double( y2 - y1 ) / double( x2 - x1 ) );
+        ty = double( y1 );
+        if ( x1 > x2 )
+        {
+            for ( int i = x1; i >= x2; i-- )
+            {
+                setXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) );
+                writeData( usedColor );
+                ty = ty - delta;
+            }
+        }
+        else
+        {
+            for ( int i = x1; i <= x2; i++ )
+            {
+                setXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) );
+                writeData( usedColor );
+                ty = ty + delta;
+            }
+        }
+        _lcd_pin_cs = HIGH;
+    }
+    else
+    {
+        unsigned short usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color;
+        _lcd_pin_cs = LOW;
+        delta = ( float( x2 - x1 ) / float( y2 - y1 ) );
+        tx = float( x1 );
+        if ( y1 > y2 )
+        {
+            for ( int i = y2 + 1; i > y1; i-- )
+            {
+                setXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i );
+                writeData( usedColor );
+                tx = tx + delta;
+            }
+        }
+        else
+        {
+            for ( int i = y1; i < y2 + 1; i++ )
+            {
+                setXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i );
+                writeData( usedColor );
+                tx = tx + delta;
+            }
+        }
+        _lcd_pin_cs = HIGH;
+    }
+
+    clearXY();
+}
+
+void SSD1289::DrawRect( 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 )
+
+    drawHLine( x1, y1, x2 - x1, color );
+    drawHLine( x1, y2, x2 - x1, color );
+    drawVLine( x1, y1, y2 - y1, color );
+    drawVLine( x2, y1, y2 - y1, color );
+}
+
+void SSD1289::DrawRoundRect( 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 )
+
+    if ( ( x2 - x1 ) > 4 && ( y2 - y1 ) > 4 )
+    {
+        DrawPixel( x1 + 1, y1 + 1, color );
+        DrawPixel( x2 - 1, y1 + 1, color );
+        DrawPixel( x1 + 1, y2 - 1, color );
+        DrawPixel( x2 - 1, y2 - 1, color );
+        drawHLine( x1 + 2, y1, x2 - x1 - 4, color );
+        drawHLine( x1 + 2, y2, x2 - x1 - 4, color );
+        drawVLine( x1, y1 + 2, y2 - y1 - 4, color );
+        drawVLine( x2, y1 + 2, y2 - y1 - 4, color );
+    }
+}
+
+void SSD1289::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 );
+
+    if ( _orientation == PORTRAIT )
+    {
+        for ( int i = 0; i < ( ( y2 - y1 ) / 2 ) + 1; i++ )
+        {
+            drawHLine( x1, y1 + i, x2 - x1, color );
+            drawHLine( x1, y2 - i, x2 - x1, color );
+        }
+    }
+    else
+    {
+        for ( int i = 0; i < ( ( x2 - x1 ) / 2 ) + 1; i++ )
+        {
+            drawVLine( x1 + i, y1, y2 - y1, color );
+            drawVLine( x2 - i, y1, y2 - y1, color );
+        }
+    }
+}
+
+void SSD1289::FillRoundRect( 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 )
+
+    if ( ( x2 - x1 ) > 4 && ( y2 - y1 ) > 4 )
+    {
+        for ( int i = 0; i < ( ( y2 - y1 ) / 2 ) + 1; i++ )
+        {
+            switch ( i )
+            {
+                case 0:
+                    drawHLine( x1 + 2, y1 + i, x2 - x1 - 4, color );
+                    drawHLine( x1 + 2, y2 - i, x2 - x1 - 4, color );
+                    break;
+
+                case 1:
+                    drawHLine( x1 + 1, y1 + i, x2 - x1 - 2, color );
+                    drawHLine( x1 + 1, y2 - i, x2 - x1 - 2, color );
+                    break;
+
+                default:
+                    drawHLine( x1, y1 + i, x2 - x1, color );
+                    drawHLine( x1, y2 - i, x2 - x1, color );
+                    break;
+            }
+        }
+    }
+}
+
+void SSD1289::DrawCircle( unsigned short x, unsigned short y, unsigned short radius, int color )
+{
+    int f = 1 - radius;
+    int ddF_x = 1;
+    int ddF_y = -2 * radius;
+    int x1 = 0;
+    int y1 = radius;
+    unsigned short usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color;
+
+    _lcd_pin_cs = LOW;
+    setXY( x, y + radius, x, y + radius );
+    writeData( usedColor );
+    setXY( x, y - radius, x, y - radius );
+    writeData( usedColor );
+    setXY( x + radius, y, x + radius, y );
+    writeData( usedColor );
+    setXY( x - radius, y, x - radius, y );
+    writeData( usedColor );
+
+    while ( x1 < y1 )
+    {
+        if ( f >= 0 )
+        {
+            y1--;
+            ddF_y += 2;
+            f += ddF_y;
+        }
+        x1++;
+        ddF_x += 2;
+        f += ddF_x;
+        setXY( x + x1, y + y1, x + x1, y + y1 );
+        writeData( usedColor );
+        setXY( x - x1, y + y1, x - x1, y + y1 );
+        writeData( usedColor );
+        setXY( x + x1, y - y1, x + x1, y - y1 );
+        writeData( usedColor );
+        setXY( x - x1, y - y1, x - x1, y - y1 );
+        writeData( usedColor );
+        setXY( x + y1, y + x1, x + y1, y + x1 );
+        writeData( usedColor );
+        setXY( x - y1, y + x1, x - y1, y + x1 );
+        writeData( usedColor );
+        setXY( x + y1, y - x1, x + y1, y - x1 );
+        writeData( usedColor );
+        setXY( x - y1, y - x1, x - y1, y - x1 );
+        writeData( usedColor );
+    }
+    _lcd_pin_cs = HIGH;
+    clearXY();
+}
+
+void SSD1289::FillCircle( unsigned short x, unsigned short y, unsigned short radius, int color )
+{
+    unsigned short usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color;
+    _lcd_pin_cs = LOW;
+    for ( int y1 = -radius; y1 <= radius; y1++ )
+        for ( int x1 = -radius; x1 <= radius; x1++ )
+            if ( x1 * x1 + y1 * y1 <= radius * radius )
+            {
+                setXY( x + x1, y + y1, x + x1, y + y1 );
+                writeData( usedColor );
+            }
+    _lcd_pin_cs = HIGH;
+    clearXY();
+}
+
+void SSD1289::Print( const char *str, unsigned short x, unsigned short y, int fgColor, int bgColor, unsigned short deg )
+{
+    int stl, i;
+
+    stl = strlen( str );
+
+    if ( _orientation == PORTRAIT )
+    {
+        if ( x == RIGHT )
+            x = ( _disp_width + 1 ) - ( stl * _font.width );
+        if ( x == CENTER )
+            x = ( ( _disp_width + 1 ) - ( stl * _font.width ) ) / 2;
+    }
+    else
+    {
+        if ( x == RIGHT )
+            x = ( _disp_height + 1 ) - ( stl * _font.width );
+        if ( x == CENTER )
+            x = ( ( _disp_height + 1 ) - ( stl * _font.width ) ) / 2;
+    }
+
+    for ( i = 0; i < stl; i++ )
+        if ( deg == 0 )
+            printChar( *str++, x + ( i * ( _font.width ) ), y, fgColor, bgColor );
+        else
+            rotateChar( *str++, x, y, i, fgColor, bgColor, deg );
+}
+
+void SSD1289::DrawBitmap( unsigned short x, unsigned short y, unsigned short sx, unsigned short sy, bitmap_t data, unsigned char scale )
+{
+    int tx, ty, tc, tsx, tsy;
+
+    if ( scale == 1 )
+    {
+        if ( _orientation == PORTRAIT )
+        {
+            _lcd_pin_cs = LOW;
+            setXY( x, y, x + sx - 1, y + sy - 1 );
+            for ( tc = 0; tc < ( sx * sy ); tc++ )
+                writeData( data[ tc ] );
+            _lcd_pin_cs = HIGH;
+        }
+        else
+        {
+            _lcd_pin_cs = LOW;
+            for ( ty = 0; ty < sy; ty++ )
+            {
+                setXY( x, y + ty, x + sx - 1, y + ty );
+                for ( tx = sx; tx >= 0; tx-- )
+                    writeData( data[ ( ty * sx ) + tx ] );
+            }
+            _lcd_pin_cs = HIGH;
+        }
+    }
+    else
+    {
+        if ( _orientation == PORTRAIT )
+        {
+            _lcd_pin_cs = LOW;
+            for ( ty = 0; ty < sy; ty++ )
+            {
+                setXY( x, y + ( ty * scale ), x + ( ( sx * scale ) - 1 ), y + ( ty * scale ) + scale );
+                for ( tsy = 0; tsy < scale; tsy++ )
+                    for ( tx = 0; tx < sx; tx++ )
+                        for ( tsx = 0; tsx < scale; tsx++ )
+                            writeData( data[ ( ty * sx ) + tx ] );
+            }
+            _lcd_pin_cs = HIGH;
+        }
+        else
+        {
+            _lcd_pin_cs = LOW;
+            for ( ty = 0; ty < sy; ty++ )
+            {
+                for ( tsy = 0; tsy < scale; tsy++ )
+                {
+                    setXY( x, y + ( ty * scale ) + tsy, x + ( ( sx * scale ) - 1 ), y + ( ty * scale ) + tsy );
+                    for ( tx = sx; tx >= 0; tx-- )
+                        for ( tsx = 0; tsx < scale; tsx++ )
+                            writeData( data[ ( ty * sx ) + tx ] );
+                }
+            }
+            _lcd_pin_cs = HIGH;
+        }
+    }
+    clearXY();
+}
+
+void SSD1289::DrawBitmap( unsigned short x, unsigned short y, unsigned short sx, unsigned short sy, bitmap_t data, unsigned short deg, unsigned short rox, unsigned short roy )
+{
+    int tx, ty, newx, newy;
+    double radian;
+    radian = deg * 0.0175;
+
+    if ( deg == 0 )
+        DrawBitmap( x, y, sx, sy, data );
+    else
+    {
+        _lcd_pin_cs = LOW;
+        for ( ty = 0; ty < sy; ty++ )
+            for ( tx = 0; tx < sx; tx++ )
+            {
+                newx = x + rox + ( ( ( tx - rox ) * cos( radian ) ) - ( ( ty - roy ) * sin( radian ) ) );
+                newy = y + roy + ( ( ( ty - roy ) * cos( radian ) ) + ( ( tx - rox ) * sin( radian ) ) );
+
+                setXY( newx, newy, newx, newy );
+                writeData( data[ ( ty * sx ) + tx ] );
+            }
+        _lcd_pin_cs = HIGH;
+    }
+    clearXY();
 }
 
 void SSD1289::writeCmd( unsigned short cmd )
 {
-    _lcd_pin_rs = 0;
-    _lcd_pin_cs = 0;
+    _lcd_pin_rs = LOW;
+    _lcd_pin_cs = LOW;
     _lcd_port->write( cmd );
     pulseLow( _lcd_pin_wr );
-    _lcd_pin_cs = 1;
+    _lcd_pin_cs = HIGH;
 }
 
 void SSD1289::writeData( unsigned short data )
 {
-    _lcd_pin_rs = 1;
-    _lcd_pin_cs = 0;
-    _lcd_port->write( cmd );
+    _lcd_pin_rs = HIGH;
+    _lcd_pin_cs = LOW;
+    _lcd_port->write( data );
     pulseLow( _lcd_pin_wr );
-    _lcd_pin_cs = 1;
+    _lcd_pin_cs = HIGH;
 }
 
 void SSD1289::writeCmdData( unsigned short cmd, unsigned short data )
@@ -41,3 +608,155 @@
     writeCmd( cmd );
     writeData( data );
 }
+
+void SSD1289::setXY( uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2 )
+{
+    if ( _orientation == LANDSCAPE )
+    {
+        swap( uint16_t, x1, y1 )
+        swap( uint16_t, x2, y2 )
+        y1 = _disp_height - y1;
+        y2 = _disp_height - y2;
+        swap( uint16_t, y1, y2 )
+    }
+
+    writeCmdData( 0x44, ( x2 << 8 ) + x1 );
+    writeCmdData( 0x45, y1 );
+    writeCmdData( 0x46, y2 );
+    writeCmdData( 0x4e, x1 );
+    writeCmdData( 0x4f, y1 );
+    writeCmd( 0x22 );
+}
+
+void SSD1289::clearXY()
+{
+    if ( _orientation == PORTRAIT )
+        setXY( 0, 0, _disp_width, _disp_height );
+    else
+        setXY( 0, 0, _disp_height, _disp_width );
+}
+
+void SSD1289::drawHLine( unsigned short x, unsigned short y, unsigned short len, int color )
+{
+    unsigned short usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color;
+    
+    _lcd_pin_cs = LOW;
+    setXY( x, y, x + len, y );
+    for ( int i = 0; i < len + 1; i++ )
+        writeData( usedColor );
+    _lcd_pin_cs = HIGH;
+    clearXY();
+}
+
+void SSD1289::drawVLine( unsigned short x, unsigned short y, unsigned short len, int color )
+{
+    unsigned short usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned short ) color;
+    
+    _lcd_pin_cs = LOW;
+    setXY( x, y, x, y + len );
+    for ( int i = 0; i < len; i++ )
+        writeData( usedColor );
+    _lcd_pin_cs = HIGH;
+    clearXY();
+}
+
+void SSD1289::printChar( char c, unsigned short x, unsigned short y, int fgColor, int bgColor )
+{
+    uint8_t i, ch;
+    uint16_t j;
+    uint16_t temp;
+    unsigned short usedColorFG = fgColor == -1 ? _background : fgColor == -2 ? _foreground : ( unsigned short ) fgColor;
+    unsigned short usedColorBG = bgColor == -1 ? _background : bgColor == -2 ? _foreground : ( unsigned short ) bgColor;
+
+    _lcd_pin_cs = LOW;
+
+    if ( _orientation == PORTRAIT )
+    {
+        setXY( x, y, x + _font.width - 1, y + _font.height - 1 );
+
+        temp = ( ( c - _font.offset ) * ( ( _font.width / 8 ) * _font.height ) ) + 4;
+        for ( j = 0; j < ( ( _font.width / 8 ) * _font.height ); j++ )
+        {
+            ch = _font.font[ temp ];
+            for ( i = 0; i < 8; i++ )
+            {
+                if ( ( ch & ( 1 << ( 7 - i ) ) ) != 0 )
+                    writeData( usedColorFG );
+                else
+                    writeData( usedColorBG );
+            }
+            temp++;
+        }
+    }
+    else
+    {
+        temp = ( ( c - _font.offset ) * ( ( _font.width / 8 ) * _font.height ) ) + 4;
+
+        for ( j = 0; j < ( ( _font.width / 8 ) * _font.height ); j += ( _font.width / 8 ) )
+        {
+            setXY( x, y + ( j / ( _font.width / 8 ) ), x + _font.width - 1, y + ( j / ( _font.width / 8 ) ) );
+            for ( int zz = ( _font.width / 8 ) - 1; zz >= 0; zz-- )
+            {
+                ch = _font.font[ temp + zz ];
+                for ( i = 0; i < 8; i++ )
+                {
+                    if ( ( ch & ( 1 << i ) ) != 0 )
+                        writeData( usedColorFG );
+                    else
+                        writeData( usedColorBG );
+                }
+            }
+            temp += ( _font.width / 8 );
+        }
+    }
+    _lcd_pin_cs = HIGH;
+    clearXY();
+}
+
+void SSD1289::rotateChar( char c, unsigned short x, unsigned short y, int pos, int fgColor, int bgColor, unsigned short deg )
+{
+    uint8_t i, j, ch;
+    uint16_t temp;
+    int newx, newy;
+    double radian;
+    radian = deg * 0.0175;
+    
+    unsigned short usedColorFG = fgColor == -1 ? _background : fgColor == -2 ? _foreground : ( unsigned short ) fgColor;
+    unsigned short usedColorBG = bgColor == -1 ? _background : bgColor == -2 ? _foreground : ( unsigned short ) bgColor;
+
+    _lcd_pin_cs = LOW;
+
+    temp = ( ( c - _font.offset ) * ( ( _font.width / 8 ) * _font.height ) ) + 4;
+    for ( j = 0; j < _font.height; j++ )
+    {
+        for ( int zz = 0; zz < ( _font.width / 8 ); zz++ )
+        {
+            ch = _font.font[ temp + zz ];
+            for ( i = 0; i < 8; i++ )
+            {
+                newx = x + ( ( ( i + ( zz * 8 ) + ( pos * _font.width ) ) * cos( radian ) ) - ( ( j ) * sin( radian ) ) );
+                newy = y + ( ( ( j ) * cos( radian ) ) + ( ( i + ( zz * 8 ) + ( pos * _font.width ) ) * sin( radian ) ) );
+
+                setXY( newx, newy, newx + 1, newy + 1 );
+
+                if ( ( ch & ( 1 << ( 7 - i ) ) ) != 0 )
+                    writeData( usedColorFG );
+                else
+                    writeData( usedColorBG );
+            }
+        }
+        temp += ( _font.width / 8 );
+    }
+    _lcd_pin_cs = HIGH;
+    clearXY();
+}
+
+int SSD1289::_getc()
+{
+    return ( -1 );
+}
+
+int SSD1289::_putc( int value )
+{
+    return ( value );
+}