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
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 }
Generated on Wed Jul 13 2022 15:07:27 by 1.7.2