Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Wed Jul 13 2022 15:38:41 by
1.7.2