A library for LPM013M126A – JDI Color Memory LCD. This library is an inherited class from the “GraphicDisplay”, and Its functions are similar to “C12832_lcd” or ”SPI_TFT” library.

Dependents:   Test_ColorMemLCD rIoTwear_LCD

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ColorMemLCD.cpp Source File

ColorMemLCD.cpp

00001 /*
00002  * mbed library for the JDI color memory LCD LPM013M126A
00003  * derived from C12832_lcd
00004  * Copyright (c) 2016  Tadayuki Okamoto 
00005  * Released under the MIT License: http://mbed.org/license/mit
00006  *
00007  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00008  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00009  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00010  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00011  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00012  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00013  * THE SOFTWARE.
00014  */
00015 
00016 
00017 #include "ColorMemLCD.h"
00018 #include "mbed.h"
00019 
00020 /** @def
00021  * LCD_Color SPI commands
00022  */
00023 #define LCD_COLOR_CMD_UPDATE            (0x90) //!< Update Mode (4bit Data Mode)
00024 #define LCD_COLOR_CMD_ALL_CLEAR         (0x20) //!< All Clear Mode
00025 #define LCD_COLOR_CMD_NO_UPDATE         (0x00) //!< No Update Mode
00026 #define LCD_COLOR_CMD_BLINKING_WHITE    (0x18) //!< Display Blinking Color Mode (White)
00027 #define LCD_COLOR_CMD_BLINKING_BLACK    (0x10) //!< Display Blinking Color Mode (Black)
00028 #define LCD_COLOR_CMD_INVERSION         (0x14) //!< Display Inversion Mode
00029 
00030 /** Create a SPI_LCD object connected to SPI */
00031 ColorMemLCD::ColorMemLCD( PinName mosi, PinName miso, PinName sclk, PinName cs, PinName disp, PinName power, const char *name )
00032     : GraphicsDisplay( name ), _spi( mosi, miso, sclk ), _cs( cs ), _disp( disp ), _power( power )
00033 {
00034     /* initialize signal level */
00035     _power = 0;
00036     _disp  = 0;
00037     _cs    = 0;
00038     wait_us( 100 );
00039 
00040     /* initialize lcd module */
00041     _power = 1;
00042     _spi.format( 8,0 );         // 8bit mode3
00043     _spi.frequency( 2000000 );  // 2 Mhz SPI clock 
00044     _spi.write( 0x00 );         // dummy
00045     polarity = 0;
00046     blink_cmd = 0x00;
00047 
00048     /* initialize variables */
00049     char_x = 0;
00050     char_y = 0;
00051     trans_mode = LCD_TRANSMODE_OPAQUE;
00052     window_x = 0;
00053     window_y = 0;
00054     window_w = LCD_DISP_WIDTH;
00055     window_h = LCD_DISP_HEIGHT_MAX_BUF;
00056 
00057     /* set default color */
00058     foreground( LCD_COLOR_WHITE );
00059     background( LCD_COLOR_BLACK );
00060 
00061     /* initialize temporary buffer */
00062     memset( &cmd_buf[0], 0, sizeof(cmd_buf) );
00063     memset( &disp_buf[0], (char)( (_background & 0x0F ) | ( (_background & 0x0F ) << 4 ) ), sizeof(disp_buf) );
00064     memset( &file_buf[0], 0, sizeof(file_buf) );
00065 
00066     /* display turn ON */
00067     command_AllClear();
00068     _disp = 1;
00069 }
00070 
00071 
00072 /** Get the width of the screen in pixel */
00073 int ColorMemLCD::width()
00074 {
00075     return LCD_DISP_WIDTH;
00076 }
00077 
00078 
00079 /** Get the height of the screen in pixel */
00080 int ColorMemLCD::height()
00081 {
00082     return LCD_DISP_HEIGHT;
00083 }
00084 
00085 
00086 /** Set window region */
00087 void ColorMemLCD::window( int x, int y, int w, int h )
00088 {
00089 #if ( LCD_DEVICE_HEIGHT != LCD_DISP_HEIGHT_MAX_BUF )
00090     if( ( ( x & 0x01 ) == 0x01 )||
00091         ( ( w & 0x01 ) == 0x01 ) ) {
00092         /* Parameter Error */
00093         GraphicsDisplay::window( x, y, w, h );
00094         return;
00095     }
00096 
00097     /* adjust region */
00098     if( x + w > LCD_DISP_WIDTH ) {
00099         w = LCD_DISP_WIDTH - x;
00100     }
00101 
00102     if( h > ( ( LCD_DISP_WIDTH / 2 ) * LCD_DISP_HEIGHT_MAX_BUF ) / ( w / 2 )  ) {
00103         h = ( ( LCD_DISP_WIDTH / 2 ) * LCD_DISP_HEIGHT_MAX_BUF ) / ( w / 2 );
00104     }
00105 
00106     if( ( window_x == x )&&
00107         ( window_y == y )&&
00108         ( window_w == w )&&
00109         ( window_h == h ) ) {
00110         /* Same Area */
00111         return;
00112     }
00113 
00114     window_x = x;
00115     window_y = y;
00116     window_w = w;
00117     window_h = h;
00118 
00119     /* Initialize Buffer */
00120     memset( &disp_buf[0], (char)( (_background & 0x0F ) | ( (_background & 0x0F ) << 4 ) ), sizeof(disp_buf) );
00121 
00122 #endif /* ( LCD_DEVICE_HEIGHT != LCD_DISP_HEIGHT_MAX_BUF ) */
00123 
00124     GraphicsDisplay::window( x, y, w, h );
00125 }
00126 
00127 
00128 /** Set a pixel on the window memory */
00129 void ColorMemLCD::pixel( int x, int y, int color )
00130 {
00131     if( ( window_x > x )||
00132         ( ( window_x + window_w ) <= x )||
00133         ( window_y > y )||
00134         ( ( window_y + window_h ) <= y ) ) {
00135         /* out of display buffer */
00136         return;
00137     }
00138 
00139     if( ( x % 2 ) == 0 ) {
00140         disp_buf[ ( (window_w / 2) * ( y - window_y ) ) + ( ( x - window_x ) / 2 ) ] &= 0x0F;
00141         disp_buf[ ( (window_w / 2) * ( y - window_y ) ) + ( ( x - window_x ) / 2 ) ] |= ( ( color & 0x0F ) << 4 );
00142     }
00143     else {
00144         disp_buf[ ( (window_w / 2) * ( y - window_y ) ) + ( ( x - window_x ) / 2 ) ] &= 0xF0;
00145         disp_buf[ ( (window_w / 2) * ( y - window_y ) ) + ( ( x - window_x ) / 2 ) ] |= ( ( color & 0x0F )      );
00146     }
00147 }
00148 
00149 
00150 /** Set a pixel - for transrucent mode */
00151 void ColorMemLCD::pixel_alpha( int x, int y, int color )
00152 {
00153     if( ( window_x > x )||
00154         ( ( window_x + window_w ) <= x )||
00155         ( window_y > y )||
00156         ( ( window_y + window_h ) <= y ) ) {
00157         /* out of display buffer */
00158         return;
00159     }
00160 
00161     if( ( x % 2 ) == 0 ) {
00162         disp_buf[ ( (window_w / 2) * ( y - window_y ) ) + ( ( x - window_x ) / 2 ) ] &= ( ( ( color & 0x0F ) << 4 ) | 0x0F );
00163     }
00164     else {
00165         disp_buf[ ( (window_w / 2) * ( y - window_y ) ) + ( ( x - window_x ) / 2 ) ] &= ( ( ( color & 0x0F )      ) | 0xF0 );
00166     }
00167 }
00168 
00169 
00170 /** Fill the window memory with background color */
00171 void ColorMemLCD::cls( void )
00172 {
00173     memset( &disp_buf[0], (char)( (_background & 0x0F ) | ( (_background & 0x0F ) << 4 ) ), sizeof(disp_buf) );
00174 }
00175 
00176 
00177 /** draw a circle */
00178 void ColorMemLCD::circle( int x0, int y0, int r, int color )
00179 {
00180     int x = -r;
00181     int y = 0;
00182     int err = 2 - (2*r);
00183     int e2 = err;
00184 
00185     do {
00186         pixel( x0-x, y0+y, color );
00187         pixel( x0+x, y0+y, color );
00188         pixel( x0+x, y0-y, color );
00189         pixel( x0-x, y0-y, color );
00190         e2 = err;
00191         if( e2 <= y ) {
00192             err += ( ( ++y ) * 2 ) + 1;
00193             if( ( -x == y )&&( e2 <= x ) ) {
00194                 e2 = 0;
00195             }
00196         }
00197         if( e2 > x ) {
00198             err += ( ( ++x ) * 2 ) + 1;
00199         }
00200     } while (x <= 0);
00201 }
00202 
00203 
00204 /** draw a filled circle */
00205 void ColorMemLCD::fillcircle( int x0, int y0, int r, int color )
00206 {
00207     int x = -r;
00208     int y = 0;
00209     int err = 2 - (2*r);
00210     int e2 = err;
00211 
00212     do {
00213         vline( x0-x, y0-y, y0+y, color );
00214         vline( x0+x, y0-y, y0+y, color );
00215         e2 = err;
00216         if( e2 <= y ) {
00217             err += ( ( ++y ) * 2 ) + 1;
00218             if( ( -x == y )&&( e2 <= x ) ) {
00219                 e2 = 0;
00220             }
00221         }
00222         if( e2 > x ) {
00223             err += ( ( ++x ) * 2 ) + 1;
00224         }
00225     } while (x <= 0);
00226 }
00227 
00228 
00229 /** draw a horizontal line */
00230 void ColorMemLCD::hline( int x0, int x1, int y, int color )
00231 {
00232     int x;
00233     int direction;
00234 
00235     if( x0 == x1 ) {
00236         pixel( x0, y, color );
00237         return;
00238     }
00239     else if( x0 > x1 ) {
00240         direction = -1;
00241     }
00242     else {
00243         direction = 1;
00244     }
00245 
00246     for( x = x0 ; x <= x1 ; x += direction ) {
00247         pixel( x, y, color );
00248     }
00249 }
00250 
00251 
00252 /** draw a vertical line */
00253 void ColorMemLCD::vline( int x, int y0, int y1, int color )
00254 {
00255     int y;
00256     int direction;
00257 
00258     if( y0 == y1 ) {
00259         pixel( x, y0, color );
00260         return;
00261     }
00262     else if( y0 > y1 ) {
00263         direction = -1;
00264     }
00265     else {
00266         direction = 1;
00267     }
00268 
00269     for( y = y0 ; y <= y1 ; y += direction ) {
00270         pixel( x, y, color );
00271     }
00272 }
00273 
00274 
00275 /** draw a 1 pixel line */
00276 void ColorMemLCD::line( int x0, int y0, int x1, int y1, int color )
00277 {
00278     int dx = 0;
00279     int dy = 0;
00280     int dx_sym = 0;
00281     int dy_sym = 0;
00282     int dx_x2 = 0;
00283     int dy_x2 = 0;
00284     int di = 0;
00285 
00286     dx = x1 - x0;
00287     dy = y1 - y0;
00288 
00289     if( dx == 0 ) {        /* vertical line */
00290         vline( x0, y0, y1, color );
00291         return;
00292     }
00293     else if( dx > 0 ) {
00294         dx_sym = 1;
00295     }
00296     else {
00297         dx_sym = -1;
00298     }
00299 
00300     if( dy == 0 ) {        /* horizontal line */
00301         hline( x0, x1, y0, color );
00302         return;
00303     }
00304     else if( dy > 0 ) {
00305         dy_sym = 1;
00306     }
00307     else {
00308         dy_sym = -1;
00309     }
00310 
00311     dx = dx_sym * dx;
00312     dy = dy_sym * dy;
00313 
00314     dx_x2 = dx * 2;
00315     dy_x2 = dy * 2;
00316 
00317     if( dx >= dy ) {
00318         di = dy_x2 - dx;
00319         while ( x0 != x1 ) {
00320 
00321             pixel( x0, y0, color );
00322             x0 += dx_sym;
00323             if( di < 0 ) {
00324                 di += dy_x2;
00325             }
00326             else {
00327                 di += dy_x2 - dx_x2;
00328                 y0 += dy_sym;
00329             }
00330         }
00331         pixel( x0, y0, color );
00332     }
00333     else {
00334         di = dx_x2 - dy;
00335         while( y0 != y1 ) {
00336             pixel( x0, y0, color );
00337             y0 += dy_sym;
00338             if( di < 0 ) {
00339                 di += dx_x2;
00340             }
00341             else {
00342                 di += dx_x2 - dy_x2;
00343                 x0 += dx_sym;
00344             }
00345         }
00346         pixel( x0, y0, color );
00347     }
00348     return;
00349 }
00350 
00351 
00352 /** draw a rect */
00353 void ColorMemLCD::rect( int x0, int y0, int x1, int y1, int color )
00354 {
00355     hline( x0, x1, y0, color );
00356 
00357     vline( x0, y0, y1, color );
00358 
00359     hline( x0, x1, y1, color );
00360 
00361     vline( x1, y0, y1, color );
00362 }
00363 
00364 
00365 /** draw a filled rect */
00366 void ColorMemLCD::fillrect(int x0, int y0, int x1, int y1, int color)
00367 {
00368     int y;
00369     int direction;
00370 
00371     if( y0 == y1 ) {
00372         hline( x0, x1, y0, color );
00373         return;
00374     }
00375     else if( y0 > y1 ) {
00376         direction = -1;
00377     }
00378     else {
00379         direction = 1;
00380     }
00381 
00382     for( y = y0 ; y <= y1 ; y += direction ) {
00383         hline( x0, x1, y, color );
00384     }
00385 }
00386 
00387 
00388 /** setup cursor position */
00389 void ColorMemLCD::locate( int x, int y )
00390 {
00391     char_x = x;
00392     char_y = y;
00393 }
00394 
00395 
00396 /** calculate the max number of char in a line */
00397 int ColorMemLCD::columns()
00398 {
00399     return width() / font[1];
00400 }
00401 
00402 
00403 /** calculate the max number of columns */
00404 int ColorMemLCD::rows()
00405 {
00406     return height() / font[2];
00407 }
00408 
00409 
00410 /** put a char on the screen */
00411 int ColorMemLCD::_putc( int value )
00412 {
00413     if( value == '\n' ) {    // new line
00414         char_x = 0;
00415         char_y = char_y + font[2];
00416         if( char_y >= ( height() - font[2] ) ) {
00417             char_y = 0;
00418         }
00419     } else {
00420         character( char_x, char_y, value );
00421     }
00422     return value;
00423 }
00424 
00425 
00426 /** draw a character of selected font */
00427 void ColorMemLCD::character( int x, int y, int c )
00428 {
00429     int hor, vert, offset, bpl, j, i, b;
00430     unsigned char* zeichen;
00431     unsigned char z,w;
00432 
00433     if( (c < 31) || (c > 127) ) {
00434         return;   // test char range
00435     }
00436 
00437     // read font parameter from start of array
00438     offset  = font[0];          // bytes / char
00439     hor     = font[1];          // get hor size of font
00440     vert    = font[2];          // get vert size of font
00441     bpl     = font[3];          // bytes per line
00442 
00443     if( char_x + hor > width() ) {
00444         char_x = 0;
00445         char_y = char_y + vert;
00446         if( char_y >= height() - vert ) {
00447             char_y = 0;
00448         }
00449     }
00450     zeichen = &font[ ( ( c - 32 ) * offset ) + 4 ]; // start of char bitmap
00451     w = zeichen[0];                                 // width of actual char
00452     for( j = 0; j < vert ; j++ ) {                  //  vert line
00453         for( i = 0 ; i < hor ; i++ ) {              //  horz line
00454             z =  zeichen[ bpl * i + ( ( j & 0xF8 ) >> 3 ) + 1 ];
00455             b = 1 << ( j & 0x07 );
00456             if( ( z & b ) == 0x00 ) {
00457                 if( trans_mode == LCD_TRANSMODE_OPAQUE ) {
00458                     pixel( x + i, y + j, _background );
00459                 }
00460                 else if( trans_mode == LCD_TRANSMODE_TRANSLUCENT ) {
00461                     pixel_alpha( x + i, y + j, _background );
00462                 }
00463             } else {
00464                 pixel( x + i, y + j, _foreground );
00465             }
00466         }
00467     }
00468     if( ( w + 2 ) < hor ) {                         // x offset to next char
00469         char_x += w + 2;
00470     }
00471     else {
00472         char_x += hor;
00473     }
00474 }
00475 
00476 /** draw a symbol of same format as "character"  */
00477 void ColorMemLCD::symbol(unsigned int x, unsigned int y, unsigned char *symbol)
00478 {
00479     unsigned int hor,vert,bpl,j,i,b; 
00480     unsigned char z;
00481     
00482     hor = symbol[0];                       // get hor size of font
00483     vert = symbol[1];                      // get vert size of font
00484     bpl = symbol[2];                       // bytes per line
00485 
00486     if( char_x + hor > width() ) {
00487         char_x = 0;
00488         char_y = char_y + vert;
00489         if( char_y >= height() - vert ) {
00490             char_y = 0;
00491         }
00492     }
00493 
00494     for( j = 0; j < vert ; j++ ) {                  //  vert line
00495         for( i = 0 ; i < hor ; i++ ) {              //  horz line
00496             z =  symbol[ bpl * i + ( ( j & 0xF8 ) >> 3 ) + 1 + 3 ];
00497             b = 1 << ( j & 0x07 );
00498             if( ( z & b ) == 0x00 ) {
00499                 if( trans_mode == LCD_TRANSMODE_OPAQUE ) {
00500                     pixel( x + i, y + j, _background );
00501                 }
00502                 else if( trans_mode == LCD_TRANSMODE_TRANSLUCENT ) {
00503                     pixel_alpha( x + i, y + j, _background );
00504                 }
00505             } else {
00506                 pixel( x + i, y + j, _foreground );
00507             }
00508         }
00509     }
00510 }
00511 
00512 
00513 /** select the font  */
00514 void ColorMemLCD::set_font( unsigned char* f )
00515 {
00516     font = f;
00517 }
00518 
00519 
00520 /** set transpalent effect */
00521 void ColorMemLCD::setTransMode( char mode )
00522 {
00523     trans_mode = mode;
00524 }
00525 
00526 
00527 /** set a bitmap on the window buffer */
00528 void ColorMemLCD::Bitmap4bit( int x, int y, int w, int h, unsigned char *bitmap )
00529 {
00530     Bitmap4bit( x, y, w, h, bitmap, 0, 0, w, h );
00531 }
00532 
00533 
00534 /** set a bitmap on the window buffer  */
00535 void ColorMemLCD::Bitmap4bit( int x, int y, int w, int h, unsigned char *bitmap, int bmp_x, int bmp_y, int bmp_w, int bmp_h )
00536 {
00537     int i, j;
00538 
00539     if( ( x         < 0 )||
00540         ( y         < 0 )||
00541         ( w         <= 0 )||
00542         ( h         <= 0 )||
00543         ( bitmap == NULL )||
00544         ( bmp_x     < 0 )||
00545         ( bmp_y     < 0 )||
00546         ( bmp_w     <= 0 )||
00547         ( bmp_h     <= 0 )||
00548         ( ( x       & 0x01 ) == 0x01 )||
00549         ( ( w       & 0x01 ) == 0x01 )||
00550         ( ( bmp_x   & 0x01 ) == 0x01 )||
00551         ( ( bmp_w   & 0x01 ) == 0x01 ) ) {
00552         /* Parameter Error */
00553         return;
00554     }
00555 
00556     for( i = 0 ; i < h ; i++ ) {
00557         if( ( window_y > i + y )||
00558             ( ( window_y + window_h ) <= i + y )||
00559             ( ( bmp_h ) <= i + bmp_y ) ) {
00560             /* out of display buffer */
00561             continue;
00562         }
00563         for( j = 0 ; j < w ; j += 2 ) {
00564             if( ( window_x > j + x )||
00565                 ( ( window_x + window_w ) <= j + x )||
00566                 ( ( bmp_w ) <= j + bmp_x ) ) {
00567                 /* out of display buffer */
00568                 continue;
00569             }
00570             /* copy to display bufffer */
00571             disp_buf[ ( ( window_w / 2 ) * ( i + y - window_y ) ) + ( ( j + x - window_x ) / 2 ) ] = bitmap[ ( ( bmp_w / 2 ) * ( i + bmp_y ) ) + ( ( j + bmp_x ) / 2 ) ];
00572         }
00573     }
00574 }
00575 
00576 
00577 /** set a bitmap on the window buffer */
00578 void ColorMemLCD::Bitmap1bit( int x, int y, int w, int h, unsigned char *bitmap )
00579 {
00580     Bitmap1bit( x, y, w, h, bitmap, 0, 0, w, h );
00581 }
00582 
00583 
00584 /** set a bitmap on the window buffer  */
00585 void ColorMemLCD::Bitmap1bit( int x, int y, int w, int h, unsigned char *bitmap, int bmp_x, int bmp_y, int bmp_w, int bmp_h )
00586 {
00587     int i, j;
00588     int byte, offset;
00589 
00590     if( ( x         < 0 )||
00591         ( y         < 0 )||
00592         ( w         <= 0 )||
00593         ( h         <= 0 )||
00594         ( bitmap == NULL )||
00595         ( bmp_x     < 0 )||
00596         ( bmp_y     < 0 )||
00597         ( bmp_w     <= 0 )||
00598         ( bmp_h     <= 0 ) ) {
00599         /* Parameter Error */
00600         return;
00601     }
00602 
00603     for( i = 0 ; i < h ; i++ ) {
00604         if( ( window_y > i + y )||
00605             ( ( window_y + window_h ) <= i + y )||
00606             ( ( bmp_h ) <= i + bmp_y ) ) {
00607             /* out of display buffer */
00608             continue;
00609         }
00610         for( j = 0 ; j < w ; j ++ ) {
00611             if( ( window_x > j + x )||
00612                 ( ( window_x + window_w ) <= j + x )||
00613                 ( ( bmp_w ) <= j + bmp_x ) ) {
00614                 /* out of display buffer */
00615                 continue;
00616             }
00617             byte    = ( ( bmp_w * ( i + bmp_y ) ) + ( ( j + bmp_x ) ) ) / 8;
00618             offset  = ( ( bmp_w * ( i + bmp_y ) ) + ( ( j + bmp_x ) ) ) % 8;
00619             /* set to display bufffer */
00620             if( ( bitmap[ byte ] & ( 0x80 >> offset ) ) != 0x00 ) {
00621                 /* Foregroud */
00622                 pixel( ( j + x - window_x ), ( i + y - window_y ), _foreground );
00623             }
00624             else {
00625                 /* Backgroud */
00626                 if( trans_mode == LCD_TRANSMODE_OPAQUE ) {
00627                     pixel( ( j + x - window_x ), ( i + y - window_y ), _background );
00628                 }
00629                 else if( trans_mode == LCD_TRANSMODE_TRANSLUCENT ) {
00630                     pixel_alpha( ( j + x - window_x ), ( i + y - window_y ), _background );
00631                 }
00632             }
00633         }
00634     }
00635 }
00636 
00637 
00638 /** Transfer to the LCD from diaply buffer */
00639 void ColorMemLCD::update()
00640 {
00641     int32_t         i;
00642     int    copy_width;
00643 
00644     if( window_x + window_w < LCD_DISP_WIDTH ) {
00645         copy_width = (window_w / 2);
00646     }
00647     else {
00648         copy_width = ( ( LCD_DISP_WIDTH - window_x ) / 2 );
00649     }
00650 
00651     for( i = 0 ; i < window_h ; i++ ) {
00652 
00653         if( window_y + i > LCD_DISP_HEIGHT ){
00654             /* out of window system */
00655             break;
00656         }
00657 
00658         /* initialize command buffer */
00659         memset( &cmd_buf[0], (char)( (_background & 0x0F ) | ( (_background & 0x0F ) << 4 ) ), sizeof(cmd_buf) );
00660 
00661         /* copy to command bufffer */
00662         memcpy( &cmd_buf[(window_x/2)], &disp_buf[ (window_w / 2) * i ], copy_width );
00663 
00664         /* send cmaoond request */
00665         sendLineCommand( &cmd_buf[0], window_y + i );
00666     }
00667 }
00668 
00669 
00670 /** Transfer a 24 bit BMP to the LCD from filesytem */
00671 int ColorMemLCD::BMP_24( int x,  int y, const char *filenameBMP )
00672 {
00673     FILE*       fp;
00674     int32_t     width;
00675     int32_t     height;
00676     int16_t     data_bit_size;
00677     bool        data_direction = false; 
00678 //  uint32_t    filesize;
00679     uint32_t    data_offset;
00680     int32_t     i = 0;
00681     int32_t     j = 0;
00682     int32_t     line = 0;
00683 
00684     memset( &file_buf[0], 0, sizeof(file_buf) );
00685 
00686     fp = fopen( filenameBMP, "rb" );
00687     if( fp != NULL ) {
00688         /* read file header */
00689         fread( &file_buf[0], sizeof(char), 14, fp );
00690 
00691 //      filesize    = file_buf[ 2] + ( file_buf[ 3] << 8 ) +  ( file_buf[ 4] << 16 ) +  ( file_buf[ 5] << 24 );
00692         data_offset = file_buf[10] + ( file_buf[11] << 8 ) +  ( file_buf[12] << 16 ) +  ( file_buf[13] << 24 );
00693 
00694         if( data_offset <= 14 ) {
00695             /* error */
00696             fclose(fp);
00697             return(0);
00698         }
00699 
00700         memset( &file_buf[0], 0, sizeof(file_buf) );
00701 
00702         /* read file header */
00703         fread( &file_buf[0], sizeof(char), (data_offset - 14), fp );
00704 
00705         if( data_offset == 0x0C ) {
00706             /* OS/2 format */
00707             width       = file_buf[ 4] + ( file_buf[ 5] << 8 );
00708             height      = file_buf[ 6] + ( file_buf[ 7] << 8 );
00709             data_bit_size   = file_buf[10] + ( file_buf[11] << 8 );
00710         }
00711         else if( data_offset == 0x36 ){
00712             /* Windows format */
00713             width       = file_buf[ 4] + ( file_buf[ 5] << 8 ) + ( file_buf[ 6] << 16 ) + ( file_buf[ 7] << 24 );
00714             height      = file_buf[ 8] + ( file_buf[ 9] << 8 ) + ( file_buf[10] << 16 ) + ( file_buf[11] << 24 );
00715             data_bit_size   = file_buf[14] + ( file_buf[15] << 8 );
00716         }
00717         else{
00718             /* Unknown format */
00719             fclose(fp);
00720             return(0);
00721         }
00722 
00723         if( data_bit_size != 24 ) {
00724             /* Not 24bit format */
00725             fclose(fp);
00726             return(0);
00727         }
00728 
00729         if( height < 0 ) {
00730             height *= -1;
00731             data_direction = true;
00732         }
00733 
00734         if( data_direction == true ) {
00735             line = i;
00736         }
00737         else {
00738             line = height - i - 1;
00739         }
00740 
00741         for( i = 0; i < height; i++ ) {
00742 
00743             if( data_direction == true ) {
00744                 line = i + y;
00745             }
00746             else {
00747                 line = height - i - 1 + y;
00748             }
00749             if( line >= LCD_DISP_HEIGHT ) {
00750                 /* out of window system */
00751                 continue;
00752             }
00753 
00754             /* initialize line display data with backgroud color */
00755             memset( &cmd_buf[0], (char)( (_background & 0x0F ) | ( (_background & 0x0F ) << 4 ) ), sizeof(cmd_buf) );
00756 
00757             if( ( line > window_y )&&
00758                 ( line < window_y + window_h ) ) {
00759                 /* inside display_buffer */
00760                 memcpy( &cmd_buf[ ( window_x / 2 ) ], &disp_buf[ ( window_w / 2 ) * ( line - window_y ) ], ( window_w / 2 ) );
00761             }
00762 
00763             for( j = 0 ; j < width / 2 ; j++ ) {
00764                 /* Read pixel */
00765                 memset( &file_buf[0], 0, 6 );
00766                 if( ( ( j * 2 ) + 1 ) < width ) {
00767                     fread( &file_buf[0], sizeof(char), 6, fp );
00768                 }
00769                 else if( ( ( j * 2 ) + 1 ) == width ){
00770                     fread( &file_buf[0], sizeof(char), 3, fp );
00771                 }
00772                 else {
00773                     break;
00774                 }
00775                 if( j + ( x / 2 ) >= (LCD_DISP_WIDTH/2) ) {
00776                     /* out of window system */
00777                     continue;
00778                 }
00779                 cmd_buf[ j + ( x / 2 ) ]  = ( ( file_buf[0] & 0x80 ) >> 2 );   /* B */
00780                 cmd_buf[ j + ( x / 2 ) ] |= ( ( file_buf[1] & 0x80 ) >> 1 );   /* G */
00781                 cmd_buf[ j + ( x / 2 ) ] |=   ( file_buf[2] & 0x80 );          /* R */
00782 
00783                 if( ( ( j * 2 ) + 1 ) < width ) {
00784                     cmd_buf[ j + ( x / 2 ) ] |= ( ( file_buf[3] & 0x80 ) >> 6 );   /* B */
00785                     cmd_buf[ j + ( x / 2 ) ] |= ( ( file_buf[4] & 0x80 ) >> 5 );   /* G */
00786                     cmd_buf[ j + ( x / 2 ) ] |= ( ( file_buf[5] & 0x80 ) >> 4 );   /* R */
00787                 }
00788             }
00789 
00790             /* send cmaoond request */
00791             sendLineCommand( &cmd_buf[0], line );
00792 
00793             /* copy to display buffer */
00794             if( ( line > window_y )&&
00795                 ( line < window_y + window_h ) ) {
00796                 /* inside display_buffer */
00797                 memcpy( &disp_buf[ ( window_w / 2 ) * ( line - window_y ) ], &cmd_buf[ ( window_x / 2 ) ], ( window_w / 2 ) );
00798             }
00799         }
00800         fclose(fp);
00801     }
00802 
00803     return(1);
00804 }
00805 
00806 
00807 /** send data packet */
00808 void ColorMemLCD::sendLineCommand( char* line_cmd, int line  )
00809 {
00810     int32_t j;
00811 
00812     if( ( line < 0 )||
00813         ( line >= LCD_DEVICE_HEIGHT ) ) {
00814         /* out of device size */
00815         return;
00816     }
00817 
00818     wait_us(6);
00819     _cs = 1;
00820     wait_us(6);
00821     _spi.write( LCD_COLOR_CMD_UPDATE | ( polarity << 6 ) ); // Command
00822     _spi.write( line + 1 );             // line
00823 
00824     for( j = 0 ; j < (LCD_DISP_WIDTH/2) ; j++ ) {
00825         if( j >= (LCD_DEVICE_WIDTH/2) ) {
00826             /* out of device size */
00827             break;
00828         }
00829         _spi.write(line_cmd[j]);        // data
00830     }
00831     for( ; j < (LCD_DEVICE_WIDTH/2) ; j++ ) {
00832         /* padding to device size */
00833         _spi.write( 0x00 );
00834     }
00835 
00836     _spi.write( 0x00 );
00837     _spi.write( 0x00 );
00838     wait_us(6);
00839     _cs = 0;
00840 }
00841 
00842 
00843 /** Toggle the polarity at evry scecond */
00844 void ColorMemLCD::polling()
00845 {
00846     if( polarity == 0 ) {
00847         polarity = 1;
00848     }
00849     else {
00850         polarity = 0;
00851     }
00852 
00853     if( _cs == 1 ) {
00854         return;
00855     }
00856 
00857     command_SetState();
00858 }
00859 
00860 
00861 /** Command for setting the state of LCD */
00862 void ColorMemLCD::command_SetState()
00863 {
00864     wait_us( 6 );
00865     _cs = 1;
00866     wait_us( 6 );
00867     _spi.write( blink_cmd | ( polarity << 6 ));
00868     _spi.write( 0x00 );
00869     wait_us(6);
00870     _cs = 0;
00871 }
00872 
00873 
00874 /** Command to clear whole the LCD */
00875 void ColorMemLCD::command_AllClear()
00876 {
00877     wait_us( 6 );
00878     _cs = 1;
00879     wait_us( 6 );
00880     _spi.write( LCD_COLOR_CMD_ALL_CLEAR | ( polarity << 6 ));
00881     _spi.write( 0x00 );
00882     wait_us(6);
00883     _cs = 0;
00884 }
00885 
00886 
00887 /** Command to blink */
00888 void ColorMemLCD::setBlinkMode( char mode )
00889 {
00890     switch( mode ) {
00891         case LCD_BLINKMODE_NONE:
00892             /* Blinking None    */
00893             blink_cmd = LCD_COLOR_CMD_NO_UPDATE;
00894             break;
00895         case LCD_BLINKMODE_WHITE:
00896             /* Blinking White   */
00897             blink_cmd = LCD_COLOR_CMD_BLINKING_WHITE;
00898             break;
00899         case LCD_BLINKMODE_BLACK:
00900             /* Blinking Black   */
00901             blink_cmd = LCD_COLOR_CMD_BLINKING_BLACK;
00902             break;
00903         case LCD_BLINKMODE_INVERSE:
00904             /* Inversion Mode   */
00905             blink_cmd = LCD_COLOR_CMD_INVERSION;
00906             break;
00907         default:
00908             /* No Update */
00909             blink_cmd = LCD_COLOR_CMD_NO_UPDATE;
00910             break;
00911     }
00912 
00913     _cs = 1;
00914     wait_us( 6 );
00915     _spi.write( blink_cmd | ( polarity << 6 ));
00916     _spi.write( 0x00 );
00917     wait_us(6);
00918     _cs = 0;
00919 }