This is a port of Henning Kralsen's UTFT library for Arduino/chipKIT to mbed, refactored to make full use of C++ inheritance and access control, in order to reduce work when implementing new drivers and at the same time make the code more readable and easier to maintain. As of now supported are SSD1289 (16-bit interface), HX8340-B (serial interface) and ST7735 (serial interface). Drivers for other controllers will be added as time and resources to acquire the displays to test the code permit.

Dependents:   test SDCard capstone_display capstone_display_2 ... more

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 RESET, PinName BL, backlight_t blType, float defaultBacklight )
00026     : _disp_width( width ), _disp_height( height ), _lcd_pin_cs( CS ), _lcd_pin_rs( RS ), _lcd_pin_reset( RESET ), _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     Deactivate();
00163 }
00164 
00165 void LCD::DrawLine( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00166 {
00167     
00168     double delta, tx, ty;
00169 
00170     if ( ( ( x2 - x1 ) < 0 ) )
00171     {
00172         swap( ushort, x1, x2 )
00173         swap( ushort, y1, y2 )
00174     }
00175     if ( ( ( y2 - y1 ) < 0 ) )
00176     {
00177         swap( ushort, x1, x2 )
00178         swap( ushort, y1, y2 )
00179     }
00180 
00181     if ( y1 == y2 )
00182     {
00183         if ( x1 > x2 )
00184             swap( ushort, x1, x2 )
00185         DrawHLine( x1, y1, x2 - x1, color );
00186     }
00187     else if ( x1 == x2 )
00188     {
00189         if ( y1 > y2 )
00190             swap( ushort, y1, y2 )
00191         DrawVLine( x1, y1, y2 - y1, color );
00192     }
00193     else
00194     {
00195         unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00196         Activate();
00197         if ( abs( x2 - x1 ) > abs( y2 - y1 ) )
00198         {
00199             delta = ( double( y2 - y1 ) / double( x2 - x1 ) );
00200             ty = double( y1 );
00201             if ( x1 > x2 )
00202             {
00203                 for ( int i = x1; i >= x2; i-- )
00204                 {
00205                     SetXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) );
00206                     SetPixelColor( usedColor );
00207                     ty = ty - delta;
00208                 }
00209             }
00210             else
00211             {
00212                 for ( int i = x1; i <= x2; i++ )
00213                 {
00214                     SetXY( i, int( ty + 0.5 ), i, int( ty + 0.5 ) );
00215                     SetPixelColor( usedColor );
00216                     ty = ty + delta;
00217                 }
00218             }
00219         }
00220         else
00221         {
00222             delta = ( float( x2 - x1 ) / float( y2 - y1 ) );
00223             tx = float( x1 );
00224             if ( y1 > y2 )
00225             {
00226                 for ( int i = y2 + 1; i > y1; i-- )
00227                 {
00228                     SetXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i );
00229                     SetPixelColor( usedColor );
00230                     tx = tx + delta;
00231                 }
00232             }
00233             else
00234             {
00235                 for ( int i = y1; i < y2 + 1; i++ )
00236                 {
00237                     SetXY( int( tx + 0.5 ), i, int( tx + 0.5 ), i );
00238                     SetPixelColor( usedColor );
00239                     tx = tx + delta;
00240                 }
00241             }
00242         }
00243         Deactivate();
00244     }
00245 }
00246 
00247 void LCD::DrawRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00248 {
00249     if ( x1 > x2 ) swap( ushort, x1, x2 )
00250     if ( y1 > y2 ) swap( ushort, y1, y2 )
00251 
00252     DrawHLine( x1, y1, x2 - x1, color );
00253     DrawHLine( x1, y2, x2 - x1, color );
00254     DrawVLine( x1, y1, y2 - y1, color );
00255     DrawVLine( x2, y1, y2 - y1, color );
00256 }
00257 
00258 void LCD::DrawRoundRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00259 {
00260     if ( x1 > x2 ) swap( ushort, x1, x2 )
00261     if ( y1 > y2 ) swap( ushort, y1, y2 )
00262 
00263     if ( ( x2 - x1 ) > 4 && ( y2 - y1 ) > 4 )
00264     {
00265         DrawPixel( x1 + 1, y1 + 1, color );
00266         DrawPixel( x2 - 1, y1 + 1, color );
00267         DrawPixel( x1 + 1, y2 - 1, color );
00268         DrawPixel( x2 - 1, y2 - 1, color );
00269         DrawHLine( x1 + 2, y1, x2 - x1 - 4, color );
00270         DrawHLine( x1 + 2, y2, x2 - x1 - 4, color );
00271         DrawVLine( x1, y1 + 2, y2 - y1 - 4, color );
00272         DrawVLine( x2, y1 + 2, y2 - y1 - 4, color );
00273     }
00274 }
00275 
00276 void LCD::FillRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00277 {
00278     if ( x1 > x2 ) swap( ushort, x1, x2 );
00279     if ( y1 > y2 ) swap( ushort, y1, y2 );
00280 
00281     for ( int i = 0; i < ( ( y2 - y1 ) / 2 ) + 1; i++ )
00282     {
00283         DrawHLine( x1, y1 + i, x2 - x1, color );
00284         DrawHLine( x1, y2 - i, x2 - x1, color );
00285     }
00286 }
00287 
00288 void LCD::FillRoundRect( unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, int color )
00289 {
00290     if ( x1 > x2 ) swap( ushort, x1, x2 )
00291     if ( y1 > y2 ) swap( ushort, y1, y2 )
00292 
00293     if ( ( x2 - x1 ) > 4 && ( y2 - y1 ) > 4 )
00294     {
00295         for ( int i = 0; i < ( ( y2 - y1 ) / 2 ) + 1; i++ )
00296         {
00297             switch ( i )
00298             {
00299                 case 0:
00300                     DrawHLine( x1 + 2, y1 + i, x2 - x1 - 4, color );
00301                     DrawHLine( x1 + 2, y2 - i, x2 - x1 - 4, color );
00302                     break;
00303 
00304                 case 1:
00305                     DrawHLine( x1 + 1, y1 + i, x2 - x1 - 2, color );
00306                     DrawHLine( x1 + 1, y2 - i, x2 - x1 - 2, color );
00307                     break;
00308 
00309                 default:
00310                     DrawHLine( x1, y1 + i, x2 - x1, color );
00311                     DrawHLine( x1, y2 - i, x2 - x1, color );
00312                     break;
00313             }
00314         }
00315     }
00316 }
00317 
00318 void LCD::DrawCircle( unsigned short x, unsigned short y, unsigned short radius, int color )
00319 {
00320     int f = 1 - radius;
00321     int ddF_x = 1;
00322     int ddF_y = -2 * radius;
00323     int x1 = 0;
00324     int y1 = radius;
00325     unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00326 
00327     Activate();
00328     SetXY( x, y + radius, x, y + radius );
00329     SetPixelColor( usedColor );
00330     SetXY( x, y - radius, x, y - radius );
00331     SetPixelColor( usedColor );
00332     SetXY( x + radius, y, x + radius, y );
00333     SetPixelColor( usedColor );
00334     SetXY( x - radius, y, x - radius, y );
00335     SetPixelColor( usedColor );
00336 
00337     while ( x1 < y1 )
00338     {
00339         if ( f >= 0 )
00340         {
00341             y1--;
00342             ddF_y += 2;
00343             f += ddF_y;
00344         }
00345         x1++;
00346         ddF_x += 2;
00347         f += ddF_x;
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 - x1, y - y1, x - x1, y - y1 );
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         SetXY( x - y1, y - x1, x - y1, y - x1 );
00363         SetPixelColor( usedColor );
00364     }
00365     Deactivate();
00366 }
00367 
00368 void LCD::FillCircle( unsigned short x, unsigned short y, unsigned short radius, int color )
00369 {
00370     unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00371     Activate();
00372     for ( int y1 = -radius; y1 <= radius; y1++ )
00373         for ( int x1 = -radius; x1 <= radius; x1++ )
00374             if ( x1 * x1 + y1 * y1 <= radius * radius )
00375             {
00376                 SetXY( x + x1, y + y1, x + x1, y + y1 );
00377                 SetPixelColor( usedColor );
00378             }
00379     Deactivate();
00380 }
00381 
00382 void LCD::Print( const char *str, unsigned short x, unsigned short y, int fgColor, int bgColor, unsigned short deg )
00383 {
00384     int stl, i;
00385 
00386     stl = strlen( str );
00387 
00388     if ( x == RIGHT )
00389         x = GetWidth() - ( stl * _font->Width );
00390     if ( x == CENTER )
00391         x = ( GetWidth() - ( stl * _font->Width ) ) / 2;
00392 
00393     for ( i = 0; i < stl; i++ )
00394         if ( deg == 0 )
00395             PrintChar( *str++, x + ( i * ( _font->Width ) ), y, fgColor, bgColor );
00396         else
00397             RotateChar( *str++, x, y, i, fgColor, bgColor, deg );
00398 }
00399 
00400 void LCD::DrawBitmap( unsigned short x, unsigned short y, const bitmap_t* img, unsigned char scale )
00401 {
00402     int tx, ty, tc, tsx, tsy;
00403 
00404     Activate();
00405     if ( scale == 1 )
00406     {
00407         SetXY( x, y, x + img->Width - 1, y + img->Height - 1 );
00408 
00409         if ( img->Format == RGB16 )
00410         {
00411             const unsigned short *pixel = ( const unsigned short* ) img->PixelData;
00412             for ( tc = 0; tc < ( img->Width * img->Height ); tc++ )
00413                 SetPixelColor( *pixel++, img->Format );
00414         }
00415         else if ( img->Format == RGB18 )
00416         {
00417             const unsigned int *pixel = ( const unsigned int* ) img->PixelData;
00418             for ( tc = 0; tc < ( img->Width * img->Height ); tc++ )
00419                 SetPixelColor( *pixel++, img->Format );
00420         }
00421     }
00422     else
00423     {
00424         if ( img->Format == RGB16 )
00425         {
00426             const unsigned short *pixel = ( const unsigned short* ) img->PixelData;
00427             
00428             for ( ty = 0; ty < img->Height; ty++ )
00429             {
00430                 SetXY( x, y + ( ty * scale ), x + ( ( img->Width * scale ) - 1 ), y + ( ty * scale ) + scale );
00431                 for ( tsy = 0; tsy < scale; tsy++ )
00432                 {
00433                     for ( tx = 0; tx < img->Width; tx++ )
00434                     {
00435                         for ( tsx = 0; tsx < scale; tsx++ )
00436                             SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
00437                     }
00438                 }
00439             }
00440         }
00441         else if ( img->Format == RGB18 )
00442         {
00443             const unsigned int *pixel = ( const unsigned int* ) img->PixelData;
00444             
00445             for ( ty = 0; ty < img->Height; ty++ )
00446             {
00447                 SetXY( x, y + ( ty * scale ), x + ( ( img->Width * scale ) - 1 ), y + ( ty * scale ) + scale );
00448                 for ( tsy = 0; tsy < scale; tsy++ )
00449                 {
00450                     for ( tx = 0; tx < img->Width; tx++ )
00451                     {
00452                         for ( tsx = 0; tsx < scale; tsx++ )
00453                             SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
00454                     }
00455                 }
00456             }
00457         }
00458     }
00459     Deactivate();
00460 }
00461 
00462 void LCD::DrawBitmap( unsigned short x, unsigned short y, const bitmap_t* img, unsigned short deg, unsigned short rox, unsigned short roy )
00463 {
00464     int tx, ty, newx, newy;
00465     double radian;
00466     radian = deg * 0.0175;
00467 
00468     if ( deg == 0 )
00469         DrawBitmap( x, y, img );
00470     else
00471     {
00472         Activate();
00473         
00474         if ( img->Format == RGB16 )
00475         {
00476             const unsigned short *pixel = ( const unsigned short* ) img->PixelData;
00477             
00478             for ( ty = 0; ty < img->Height; ty++ )
00479                 for ( tx = 0; tx < img->Width; tx++ )
00480                 {
00481                     newx = x + rox + ( ( ( tx - rox ) * cos( radian ) ) - ( ( ty - roy ) * sin( radian ) ) );
00482                     newy = y + roy + ( ( ( ty - roy ) * cos( radian ) ) + ( ( tx - rox ) * sin( radian ) ) );
00483     
00484                     SetXY( newx, newy, newx, newy );
00485                     SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
00486                 }
00487         }
00488         else if ( img->Format == RGB18 )
00489         {
00490             const unsigned int *pixel = ( const unsigned int* ) img->PixelData;
00491             
00492             for ( ty = 0; ty < img->Height; ty++ )
00493                 for ( tx = 0; tx < img->Width; tx++ )
00494                 {
00495                     newx = x + rox + ( ( ( tx - rox ) * cos( radian ) ) - ( ( ty - roy ) * sin( radian ) ) );
00496                     newy = y + roy + ( ( ( ty - roy ) * cos( radian ) ) + ( ( tx - rox ) * sin( radian ) ) );
00497     
00498                     SetXY( newx, newy, newx, newy );
00499                     SetPixelColor( pixel[ ( ty * img->Width ) + tx ], img->Format );
00500                 }
00501         }
00502         Deactivate();
00503     }
00504 }
00505 
00506 inline
00507 void LCD::Activate( void )
00508 {
00509     _lcd_pin_cs = LOW;
00510 }
00511 
00512 inline
00513 void LCD::Deactivate( void )
00514 {
00515     _lcd_pin_cs = HIGH;
00516 }
00517 
00518 inline
00519 void LCD::WriteCmdData( unsigned short cmd, unsigned short data )
00520 {
00521     WriteCmd( cmd );
00522     WriteData( data );
00523 }
00524 
00525 inline
00526 void LCD::ClearXY( void )
00527 {
00528     SetXY( 0, 0, GetWidth() - 1, GetHeight() - 1 );
00529 }
00530 
00531 void LCD::DrawHLine( unsigned short x, unsigned short y, unsigned short len, int color )
00532 {
00533     unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00534     
00535     Activate();
00536     SetXY( x, y, x + len, y );
00537     for ( int i = 0; i < len + 1; i++ )
00538         SetPixelColor( usedColor );
00539     Deactivate();
00540 }
00541 
00542 void LCD::DrawVLine( unsigned short x, unsigned short y, unsigned short len, int color )
00543 {
00544     unsigned int usedColor = color == -1 ? _background : color == -2 ? _foreground : ( unsigned int ) color;
00545     
00546     Activate();
00547     SetXY( x, y, x, y + len );
00548     for ( int i = 0; i < len; i++ )
00549         SetPixelColor( usedColor );
00550     Deactivate();
00551 }
00552 
00553 void LCD::PrintChar( char c, unsigned short x, unsigned short y, int fgColor, int bgColor )
00554 {
00555     uint8_t i, ch;
00556     uint16_t j;
00557     unsigned int usedColorFG = fgColor == -1 ? _background : fgColor == -2 ? _foreground : ( unsigned int ) fgColor;
00558     unsigned int usedColorBG = bgColor == -1 ? _background : bgColor == -2 ? _foreground : ( unsigned int ) bgColor;
00559     
00560     uint16_t totalCharBytes = ( _font->Width * _font->Height ) / 8;
00561     int16_t position = _font->Position[ c - _font->Offset ];
00562     if ( position == -1 ) position = 0; // will print space character
00563     
00564     Activate();
00565 
00566     SetXY( x, y, x + _font->Width - 1, y + _font->Height - 1 );
00567     
00568     for ( j = 0; j < totalCharBytes; j++ )
00569     {
00570         ch = _font->Data[ position ];
00571         for ( i = 0; i < 8; i++ )
00572         {
00573             if ( ( ch & ( 1 << ( 7 - i ) ) ) != 0 ) SetPixelColor( usedColorFG );
00574             else SetPixelColor( usedColorBG );
00575         }
00576         position++;
00577     }
00578     Deactivate();
00579 }
00580 
00581 void LCD::RotateChar( char c, unsigned short x, unsigned short y, int pos, int fgColor, int bgColor, unsigned short deg )
00582 {
00583     uint8_t i, j, ch;
00584     int newx, newy;
00585     double radian;
00586     radian = deg * 0.0175;
00587     
00588     unsigned int usedColorFG = fgColor == -1 ? _background : fgColor == -2 ? _foreground : ( unsigned int ) fgColor;
00589     unsigned int usedColorBG = bgColor == -1 ? _background : bgColor == -2 ? _foreground : ( unsigned int ) bgColor;
00590 
00591     int16_t position = _font->Position[ c - _font->Offset ];
00592     if ( position == -1 ) position = 0; // will print space character
00593     
00594     Activate();
00595     
00596     for ( j = 0; j < _font->Height; j++ )
00597     {
00598         for ( uint16_t zz = 0; zz < ( ( double ) _font->Width / 8 ); zz++ )
00599         {
00600             ch = _font->Data[ position + zz ];
00601             for ( i = 0; i < 8; i++ )
00602             {
00603                 newx = x + ( ( ( i + ( zz * 8 ) + ( pos * _font->Width ) ) * cos( radian ) ) - ( ( j ) * sin( radian ) ) );
00604                 newy = y + ( ( ( j ) * cos( radian ) ) + ( ( i + ( zz * 8 ) + ( pos * _font->Width ) ) * sin( radian ) ) );
00605 
00606                 SetXY( newx, newy, newx + 1, newy + 1 );
00607 
00608                 if ( ( ch & ( 1 << ( 7 - i ) ) ) != 0 ) SetPixelColor( usedColorFG );
00609                 else SetPixelColor( usedColorBG );
00610             }
00611         }
00612         position += ( _font->Width / 8 );
00613     }
00614 
00615     Deactivate();
00616 }