Gregor Mraczny / TFTLCD_Landtiger
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lcd_base.cpp Source File

lcd_base.cpp

00001 /*
00002  * Copyright (C)2010-2012 Henning Karlsen. All right reserved.
00003  * Copyright (C)2012 Todor Todorov.
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to:
00017  *
00018  * Free Software Foundation, Inc.
00019  * 51 Franklin St, 5th Floor, Boston, MA 02110-1301, USA
00020  *
00021  *********************************************************************/
00022 #include "lcd_base.h"
00023 #include "helpers.h"
00024 
00025 LCD::LCD( unsigned short width, unsigned short height, PinName CS, PinName RS,  PinName DIR, PinName EN, PinName LE, PinName BL, backlight_t blType, float defaultBacklight )
00026     : _disp_width( width ), _disp_height( height ), _lcd_pin_cs( CS ), _lcd_pin_rs( RS ),  _lcd_pin_dir(DIR), _lcd_pin_en(EN), _lcd_pin_le(LE), _bl_type( blType )
00027 {
00028     SetForeground();
00029     SetBackground();
00030     _font = &TerminusFont;
00031     if ( defaultBacklight < 0 ) _bl_pwm_default = 0;
00032     else if ( defaultBacklight > 1.0 ) _bl_pwm_default = 1.0;
00033     else _bl_pwm_default = defaultBacklight;
00034     if ( BL != NC )
00035     {
00036         if ( blType == Constant )
00037         {
00038             _bl_pwm = 0;
00039             _lcd_pin_bl = new DigitalOut( BL );
00040         }
00041         else
00042         {
00043             _lcd_pin_bl = 0;
00044             _bl_pwm = new PwmOut( BL );
00045             _bl_pwm->period_ms( 8.33 ); // 120 Hz
00046             _bl_pwm_current = _bl_pwm_default;
00047             // initially off
00048             *_bl_pwm = 0;
00049         }
00050         
00051     }
00052     else
00053     {
00054         _lcd_pin_bl = 0;
00055         _bl_pwm = 0;
00056     }
00057 }
00058 
00059 void LCD::Sleep( void )
00060 {
00061     if ( _lcd_pin_bl != 0 )
00062         *_lcd_pin_bl = LOW;
00063     else if ( _bl_pwm != 0 )
00064         *_bl_pwm = 0;
00065 }
00066 
00067 void LCD::WakeUp( void )
00068 {
00069     if ( _lcd_pin_bl != 0 )
00070         *_lcd_pin_bl = HIGH;
00071     else if ( _bl_pwm != 0 )
00072         *_bl_pwm = _bl_pwm_current;
00073 }
00074 
00075 inline
00076 void LCD::SetForeground( unsigned int color )
00077 {
00078     _foreground = color;
00079 }
00080 
00081 inline
00082 void LCD::SetBackground( unsigned int color )
00083 {
00084     _background = color;
00085 }
00086 
00087 void LCD::SetFont( const font_t *font )
00088 {
00089     _font = font;
00090 }
00091 
00092 inline
00093 unsigned short LCD::GetWidth( void )
00094 {
00095     if ( _orientation == LANDSCAPE || _orientation == LANDSCAPE_REV ) return _disp_height;
00096     return _disp_width;
00097 }
00098 
00099 inline
00100 unsigned short LCD::GetHeight( void )
00101 {
00102     if ( _orientation == LANDSCAPE || _orientation == LANDSCAPE_REV ) return _disp_width;
00103     return _disp_height;
00104 }
00105 
00106 inline
00107 uint8_t LCD::GetFontWidth( void )
00108 {
00109     if ( _font != 0 ) return _font->Width;
00110     return 0;
00111 }
00112 
00113 inline
00114 uint8_t LCD::GetFontHeight( void )
00115 {
00116     if ( _font != 0 ) return _font->Height;
00117     return 0;
00118 }
00119 
00120 void LCD::SetBacklightLevel( float level )
00121 {
00122     switch ( _bl_type )
00123     {
00124         case Direct:
00125             if ( _bl_pwm != 0 )
00126             {
00127                 *_bl_pwm = level;
00128                 _bl_pwm_current = level;
00129             }
00130             break;
00131             
00132         case Indirect:
00133             break;
00134         case Constant:
00135         default:
00136             break;
00137     }
00138 }
00139 
00140 void LCD::FillScreen( int color )
00141 {
00142     unsigned int rgb = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00143     Activate();
00144     ClearXY();
00145     for ( int i = 0; i < ( ( _disp_width ) * ( _disp_height ) ); i++ )
00146         SetPixelColor( rgb );
00147     Deactivate();  
00148 }
00149 
00150 inline
00151 void LCD::ClearScreen( void )
00152 {
00153     FillScreen( -1 );
00154 }
00155 
00156 void LCD::DrawPixel( unsigned short x, unsigned short y, int color )
00157 {
00158     Activate();
00159     SetXY( x, y, x, y );
00160     SetPixelColor( color == -1 ? _background :
00161                     color == -2 ? _foreground : color );
00162 }
00163 
00164 void LCD::DrawLine( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00165 {
00166     double delta, tx, ty;
00167 
00168     if ( ( ( x2 - x1 ) < 0 ) )
00169     {
00170         swap( ushort, x1, x2 )
00171         swap( ushort, y1, y2 )
00172     }
00173     if ( ( ( y2 - y1 ) < 0 ) )
00174     {
00175         swap( ushort, x1, x2 )
00176         swap( ushort, y1, y2 )
00177     }
00178 
00179     if ( y1 == y2 )
00180     {
00181         if ( x1 > x2 )
00182             swap( ushort, x1, x2 )
00183         DrawHLine( x1, y1, x2 - x1, color );
00184     }
00185     else if ( x1 == x2 )
00186     {
00187         if ( y1 > y2 )
00188             swap( ushort, y1, y2 )
00189         DrawVLine( x1, y1, y2 - y1, color );
00190     }
00191     else
00192     {
00193         unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00194         Activate();
00195         if ( abs( x2 - x1 ) > abs( y2 - y1 ) )
00196         {
00197             delta = ( double( y2 - y1 ) / double( x2 - x1 ) );
00198             ty = double( y1 );
00199             if ( x1 > x2 )
00200             {
00201                 for ( int i = x1; i >= x2; i-- )
00202                 {
00203                     SetXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) );
00204                     SetPixelColor( usedColor );
00205                     ty = ty - delta;
00206                 }
00207             }
00208             else
00209             {
00210                 for ( int i = x1; i <= x2; i++ )
00211                 {
00212                     SetXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) );
00213                     SetPixelColor( usedColor );
00214                     ty = ty + delta;
00215                 }
00216             }
00217         }
00218         else
00219         {
00220             delta = ( float( x2 - x1 ) / float( y2 - y1 ) );
00221             tx = float( x1 );
00222             if ( y1 > y2 )
00223             {
00224                 for ( int i = y2 + 1; i > y1; i-- )
00225                 {
00226                     SetXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i );
00227                     SetPixelColor( usedColor );
00228                     tx = tx + delta;
00229                 }
00230             }
00231             else
00232             {
00233                 for ( int i = y1; i < y2 + 1; i++ )
00234                 {
00235                     SetXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i );
00236                     SetPixelColor( usedColor );
00237                     tx = tx + delta;
00238                 }
00239             }
00240         }
00241         Deactivate();
00242     }
00243 }
00244 
00245 void LCD::DrawRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00246 {
00247     if ( x1 > x2 ) swap( ushort, x1, x2 )
00248     if ( y1 > y2 ) swap( ushort, y1, y2 )
00249 
00250     DrawHLine( x1, y1, x2 - x1, color );
00251     DrawHLine( x1, y2, x2 - x1, color );
00252     DrawVLine( x1, y1, y2 - y1, color );
00253     DrawVLine( x2, y1, y2 - y1, color );
00254 }
00255 
00256 void LCD::DrawRoundRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00257 {
00258     if ( x1 > x2 ) swap( ushort, x1, x2 )
00259     if ( y1 > y2 ) swap( ushort, y1, y2 )
00260 
00261     if ( ( x2 - x1 ) > 4 && ( y2 - y1 ) > 4 )
00262     {
00263         DrawPixel( x1 + 1, y1 + 1, color );
00264         DrawPixel( x2 - 1, y1 + 1, color );
00265         DrawPixel( x1 + 1, y2 - 1, color );
00266         DrawPixel( x2 - 1, y2 - 1, color );
00267         DrawHLine( x1 + 2, y1, x2 - x1 - 4, color );
00268         DrawHLine( x1 + 2, y2, x2 - x1 - 4, color );
00269         DrawVLine( x1, y1 + 2, y2 - y1 - 4, color );
00270         DrawVLine( x2, y1 + 2, y2 - y1 - 4, color );
00271     }
00272 }
00273 
00274 void LCD::FillRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00275 {
00276     if ( x1 > x2 ) swap( ushort, x1, x2 );
00277     if ( y1 > y2 ) swap( ushort, y1, y2 );
00278 
00279     for ( int i = 0; i < ( ( y2 - y1 ) / 2 ) + 1; i++ )
00280     {
00281         DrawHLine( x1, y1 + i, x2 - x1, color );
00282         DrawHLine( x1, y2 - i, x2 - x1, color );
00283     } 
00284 }
00285 
00286 void LCD::FillRoundRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00287 {
00288     if ( x1 > x2 ) swap( ushort, x1, x2 )
00289     if ( y1 > y2 ) swap( ushort, y1, y2 )
00290 
00291     if ( ( x2 - x1 ) > 4 && ( y2 - y1 ) > 4 )
00292     {
00293         for ( int i = 0; i < ( ( y2 - y1 ) / 2 ) + 1; i++ )
00294         {
00295             switch ( i )
00296             {
00297                 case 0:
00298                     DrawHLine( x1 + 2, y1 + i, x2 - x1 - 4, color );
00299                     DrawHLine( x1 + 2, y2 - i, x2 - x1 - 4, color );
00300                     break;
00301 
00302                 case 1:
00303                     DrawHLine( x1 + 1, y1 + i, x2 - x1 - 2, color );
00304                     DrawHLine( x1 + 1, y2 - i, x2 - x1 - 2, color );
00305                     break;
00306 
00307                 default:
00308                     DrawHLine( x1, y1 + i, x2 - x1, color );
00309                     DrawHLine( x1, y2 - i, x2 - x1, color );
00310                     break;
00311             }
00312         }
00313     }
00314 }
00315 
00316 void LCD::DrawCircle( unsigned short x, unsigned short y, unsigned short radius, int color )
00317 {
00318     int f = 1 - radius;
00319     int ddF_x = 1;
00320     int ddF_y = -2 * radius;
00321     int x1 = 0;
00322     int y1 = radius;
00323     unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00324 
00325     Activate();
00326     SetXY( x, y + radius, x, y + radius );
00327     SetPixelColor( usedColor );
00328     SetXY( x, y - radius, x, y - radius );
00329     SetPixelColor( usedColor );
00330     SetXY( x + radius, y, x + radius, y );
00331     SetPixelColor( usedColor );
00332     SetXY( x - radius, y, x - radius, y );
00333     SetPixelColor( usedColor );
00334 
00335     while ( x1 < y1 )
00336     {
00337         if ( f >= 0 )
00338         {
00339             y1--;
00340             ddF_y += 2;
00341             f += ddF_y;
00342         }
00343         x1++;
00344         ddF_x += 2;
00345         f += ddF_x;
00346         SetXY( x + x1, y + y1, x + x1, y + y1 );
00347         SetPixelColor( usedColor );
00348         SetXY( x - x1, y + y1, x - x1, y + y1 );
00349         SetPixelColor( usedColor );
00350         SetXY( x + x1, y - y1, x + x1, y - y1 );
00351         SetPixelColor( usedColor );
00352         SetXY( x - x1, y - y1, x - x1, y - y1 );
00353         SetPixelColor( usedColor );
00354         SetXY( x + y1, y + x1, x + y1, y + x1 );
00355         SetPixelColor( usedColor );
00356         SetXY( x - y1, y + x1, x - y1, y + x1 );
00357         SetPixelColor( usedColor );
00358         SetXY( x + y1, y - x1, x + y1, y - x1 );
00359         SetPixelColor( usedColor );
00360         SetXY( x - y1, y - x1, x - y1, y - x1 );
00361         SetPixelColor( usedColor );
00362     }
00363     Deactivate();
00364 }
00365 
00366 void LCD::FillCircle( unsigned short x, unsigned short y, unsigned short radius, int color )
00367 {
00368     unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00369     Activate();
00370     for ( int y1 = -radius; y1 <= radius; y1++ )
00371         for ( int x1 = -radius; x1 <= radius; x1++ )
00372             if ( x1 * x1 + y1 * y1 <= radius * radius )
00373             {
00374                 SetXY( x + x1, y + y1, x + x1, y + y1 );
00375                 SetPixelColor( usedColor );
00376             }
00377     Deactivate();
00378 }
00379 
00380 void LCD::Print( const char *str, unsigned short x, unsigned short y, int fgColor, int bgColor, unsigned short deg )
00381 {
00382     int stl, i;
00383 
00384     stl = strlen( str );
00385 
00386     if ( x == RIGHT )
00387         x = GetWidth() - ( stl * _font->Width );
00388     if ( x == CENTER )
00389         x = ( GetWidth() - ( stl * _font->Width ) ) / 2;
00390 
00391     for ( i = 0; i < stl; i++ )
00392         if ( deg == 0 )
00393             PrintChar( *str++, x + ( i * ( _font->Width ) ), y, fgColor, bgColor );
00394         else
00395             RotateChar( *str++, x, y, i, fgColor, bgColor, deg );        
00396 }
00397 
00398 void LCD::DrawBitmap( unsigned short x, unsigned short y, const bitmap_t* img, unsigned char scale )
00399 {
00400     int tx, ty, tc, tsx, tsy;
00401 
00402     Activate();
00403     if ( scale == 1 )
00404     {
00405         SetXY( x, y, x + img->Width - 1, y + img->Height - 1 );
00406 
00407         if ( img->Format == RGB16 )
00408         {
00409             const unsigned short *pixel = ( const unsigned short* ) img->PixelData;
00410             for ( tc = 0; tc < ( img->Width * img->Height ); tc++ )
00411                 SetPixelColor( *pixel++, img->Format );
00412         }
00413         else if ( img->Format == RGB18 )
00414         {
00415             const unsigned int *pixel = ( const unsigned int* ) img->PixelData;
00416             for ( tc = 0; tc < ( img->Width * img->Height ); tc++ )
00417                 SetPixelColor( *pixel++, img->Format );
00418         }
00419     }
00420     else
00421     {
00422         if ( img->Format == RGB16 )
00423         {
00424             const unsigned short *pixel = ( const unsigned short* ) img->PixelData;
00425             
00426             for ( ty = 0; ty < img->Height; ty++ )
00427             {
00428                 SetXY( x, y + ( ty * scale ), x + ( ( img->Width * scale ) - 1 ), y + ( ty * scale ) + scale );
00429                 for ( tsy = 0; tsy < scale; tsy++ )
00430                 {
00431                     for ( tx = 0; tx < img->Width; tx++ )
00432                     {
00433                         for ( tsx = 0; tsx < scale; tsx++ )
00434                             SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
00435                     }
00436                 }
00437             }
00438         }
00439         else if ( img->Format == RGB18 )
00440         {
00441             const unsigned int *pixel = ( const unsigned int* ) img->PixelData;
00442             
00443             for ( ty = 0; ty < img->Height; ty++ )
00444             {
00445                 SetXY( x, y + ( ty * scale ), x + ( ( img->Width * scale ) - 1 ), y + ( ty * scale ) + scale );
00446                 for ( tsy = 0; tsy < scale; tsy++ )
00447                 {
00448                     for ( tx = 0; tx < img->Width; tx++ )
00449                     {
00450                         for ( tsx = 0; tsx < scale; tsx++ )
00451                             SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
00452                     }
00453                 }
00454             }
00455         }
00456     }
00457     Deactivate();     
00458 }
00459 
00460 void LCD::DrawBitmap( unsigned short x, unsigned short y, const bitmap_t* img, unsigned short deg, unsigned short rox, unsigned short roy )
00461 {
00462     int tx, ty, newx, newy;
00463     double radian;
00464     radian = deg * 0.0175;
00465 
00466     if ( deg == 0 )
00467         DrawBitmap( x, y, img );
00468     else
00469     {
00470         Activate();
00471         
00472         if ( img->Format == RGB16 )
00473         {
00474             const unsigned short *pixel = ( const unsigned short* ) img->PixelData;
00475             
00476             for ( ty = 0; ty < img->Height; ty++ )
00477                 for ( tx = 0; tx < img->Width; tx++ )
00478                 {
00479                     newx = x + rox + ( ( ( tx - rox ) * cos( radian ) ) - ( ( ty - roy ) * sin( radian ) ) );
00480                     newy = y + roy + ( ( ( ty - roy ) * cos( radian ) ) + ( ( tx - rox ) * sin( radian ) ) );
00481     
00482                     SetXY( newx, newy, newx, newy );
00483                     SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
00484                 }
00485         }
00486         else if ( img->Format == RGB18 )
00487         {
00488             const unsigned int *pixel = ( const unsigned int* ) img->PixelData;
00489             
00490             for ( ty = 0; ty < img->Height; ty++ )
00491                 for ( tx = 0; tx < img->Width; tx++ )
00492                 {
00493                     newx = x + rox + ( ( ( tx - rox ) * cos( radian ) ) - ( ( ty - roy ) * sin( radian ) ) );
00494                     newy = y + roy + ( ( ( ty - roy ) * cos( radian ) ) + ( ( tx - rox ) * sin( radian ) ) );
00495     
00496                     SetXY( newx, newy, newx, newy );
00497                     SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
00498                 }
00499         }
00500         Deactivate();
00501     }
00502 }
00503 
00504 inline
00505 void LCD::Activate( void )
00506 {
00507     _lcd_pin_cs = LOW;
00508 }
00509 
00510 inline
00511 void LCD::Deactivate( void )
00512 {
00513     _lcd_pin_cs = HIGH;
00514 }
00515 
00516 inline
00517 void LCD::WriteCmdData( unsigned short cmd, unsigned short data )
00518 {
00519     WriteCmd( cmd );
00520     WriteData( data );
00521 }
00522 
00523 inline
00524 void LCD::ClearXY( void )
00525 {
00526     SetXY( 0, 0, GetWidth() - 1, GetHeight() - 1 );
00527 }
00528 
00529 void LCD::DrawHLine( unsigned short x, unsigned short y, unsigned short len, int color )
00530 {
00531     unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00532     
00533     Activate();
00534     SetXY( x, y, x + len, y );
00535     for ( int i = 0; i < len + 1; i++ )
00536         SetPixelColor( usedColor );
00537     Deactivate();
00538 }
00539 
00540 void LCD::DrawVLine( unsigned short x, unsigned short y, unsigned short len, int color )
00541 {
00542     unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00543     
00544     Activate();
00545     SetXY( x, y, x, y + len );
00546     for ( int i = 0; i < len; i++ )
00547         SetPixelColor( usedColor );
00548     Deactivate();
00549 }
00550 
00551 void LCD::PrintChar( char c, unsigned short x, unsigned short y, int fgColor, int bgColor )
00552 {
00553     uint8_t i, ch;
00554     uint16_t j;
00555     unsigned int usedColorFG = fgColor == -1 ? _background : fgColor == -2 ? _foreground : ( unsigned int ) fgColor;
00556     unsigned int usedColorBG = bgColor == -1 ? _background : bgColor == -2 ? _foreground : ( unsigned int ) bgColor;
00557     
00558     uint16_t totalCharBytes = ( _font->Width * _font->Height ) / 8;
00559     int16_t position = _font->Position[ c - _font->Offset ];
00560     if ( position == -1 ) position = 0; // will print space character
00561     
00562     Activate();
00563 
00564     SetXY( x, y, x + _font->Width - 1, y + _font->Height - 1 );
00565     
00566     for ( j = 0; j < totalCharBytes; j++ )
00567     {
00568         ch = _font->Data[ position ];
00569         for ( i = 0; i < 8; i++ )
00570         {
00571             if ( ( ch & ( 1 << ( 7 - i ) ) ) != 0 ) SetPixelColor( usedColorFG );
00572             else SetPixelColor( usedColorBG );
00573         }
00574         position++;
00575     }
00576     Deactivate();
00577 }
00578 
00579 void LCD::RotateChar( char c, unsigned short x, unsigned short y, int pos, int fgColor, int bgColor, unsigned short deg )
00580 {
00581     uint8_t i, j, ch;
00582     int newx, newy;
00583     double radian;
00584     radian = deg * 0.0175;
00585     
00586     unsigned int usedColorFG = fgColor == -1 ? _background : fgColor == -2 ? _foreground : ( unsigned int ) fgColor;
00587     unsigned int usedColorBG = bgColor == -1 ? _background : bgColor == -2 ? _foreground : ( unsigned int ) bgColor;
00588 
00589     int16_t position = _font->Position[ c - _font->Offset ];
00590     if ( position == -1 ) position = 0; // will print space character
00591     
00592     Activate();
00593     
00594     for ( j = 0; j < _font->Height; j++ )
00595     {
00596         for ( uint16_t zz = 0; zz < ( ( double ) _font->Width / 8 ); zz++ )
00597         {
00598             ch = _font->Data[ position + zz ];
00599             for ( i = 0; i < 8; i++ )
00600             {
00601                 newx = x + ( ( ( i + ( zz * 8 ) + ( pos * _font->Width ) ) * cos( radian ) ) - ( ( j ) * sin( radian ) ) );
00602                 newy = y + ( ( ( j ) * cos( radian ) ) + ( ( i + ( zz * 8 ) + ( pos * _font->Width ) ) * sin( radian ) ) );
00603 
00604                 SetXY( newx, newy, newx + 1, newy + 1 );
00605 
00606                 if ( ( ch & ( 1 << ( 7 - i ) ) ) != 0 ) SetPixelColor( usedColorFG );
00607                 else SetPixelColor( usedColorBG );
00608             }
00609         }
00610         position += ( _font->Width / 8 );
00611     }
00612 
00613     Deactivate();
00614 }
00615