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

1.28" (176x176 193ppi) 8 Color Memory LCD of ultra-low power consumption in sub uA.

Files at this revision

API Documentation at this revision

Comitter:
KURETA90
Date:
Thu Jun 23 02:08:18 2016 +0000
Child:
1:b035a997ec3f
Commit message:
First

Changed in this revision

ColorMemLCD.cpp Show annotated file Show diff for this revision Revisions of this file
ColorMemLCD.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ColorMemLCD.cpp	Thu Jun 23 02:08:18 2016 +0000
@@ -0,0 +1,920 @@
+/*
+ * mbed library for the JDI color memory LCD LPM013M126A
+ * derived from C12832_lcd
+ * Copyright (c) 2016  Tadayuki Okamoto 
+ * Released under the MIT License: http://mbed.org/license/mit
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+#include "ColorMemLCD.h"
+#include "mbed.h"
+
+/** @def
+ * LCD_Color SPI commands
+ */
+#define LCD_COLOR_CMD_UPDATE            (0x90) //!< Update Mode (4bit Data Mode)
+#define LCD_COLOR_CMD_ALL_CLEAR         (0x20) //!< All Clear Mode
+#define LCD_COLOR_CMD_NO_UPDATE         (0x00) //!< No Update Mode
+#define LCD_COLOR_CMD_BLINKING_WHITE    (0x18) //!< Display Blinking Color Mode (White)
+#define LCD_COLOR_CMD_BLINKING_BLACK    (0x10) //!< Display Blinking Color Mode (Black)
+#define LCD_COLOR_CMD_INVERSION         (0x14) //!< Display Inversion Mode
+
+/** Create a SPI_LCD object connected to SPI */
+ColorMemLCD::ColorMemLCD( PinName mosi, PinName miso, PinName sclk, PinName cs, PinName disp, PinName power, const char *name )
+    : GraphicsDisplay( name ), _spi( mosi, miso, sclk ), _cs( cs ), _disp( disp ), _power( power )
+{
+    /* initialize signal level */
+    _power = 0;
+    _disp  = 0;
+    _cs    = 0;
+    wait_us( 100 );
+
+    /* initialize lcd module */
+    _power = 1;
+    _spi.format( 8,0 );         // 8bit mode3
+    _spi.frequency( 2000000 );  // 2 Mhz SPI clock 
+    _spi.write( 0x00 );         // dummy
+    polarity = 0;
+    blink_cmd = 0x00;
+
+    /* initialize variables */
+    char_x = 0;
+    char_y = 0;
+    trans_mode = LCD_TRANSMODE_OPAQUE;
+    window_x = 0;
+    window_y = 0;
+    window_w = LCD_DISP_WIDTH;
+    window_h = LCD_DISP_HEIGHT_MAX_BUF;
+
+    /* set default color */
+    foreground( LCD_COLOR_WHITE );
+    background( LCD_COLOR_BLACK );
+
+    /* initialize temporary buffer */
+    memset( &cmd_buf[0], 0, sizeof(cmd_buf) );
+    memset( &disp_buf[0], (char)( (_background & 0x0F ) | ( (_background & 0x0F ) << 4 ) ), sizeof(disp_buf) );
+    memset( &file_buf[0], 0, sizeof(file_buf) );
+
+    /* display turn ON */
+    command_AllClear();
+    _disp = 1;
+}
+
+
+/** Get the width of the screen in pixel */
+int ColorMemLCD::width()
+{
+    return LCD_DISP_WIDTH;
+}
+
+
+/** Get the height of the screen in pixel */
+int ColorMemLCD::height()
+{
+    return LCD_DISP_HEIGHT;
+}
+
+
+/** Set window region */
+void ColorMemLCD::window( int x, int y, int w, int h )
+{
+#if ( LCD_DEVICE_HEIGHT != LCD_DISP_HEIGHT_MAX_BUF )
+    if( ( ( x & 0x01 ) == 0x01 )||
+        ( ( w & 0x01 ) == 0x01 ) ) {
+        /* Parameter Error */
+        GraphicsDisplay::window( x, y, w, h );
+        return;
+    }
+
+    /* adjust region */
+    if( x + w > LCD_DISP_WIDTH ) {
+        w = LCD_DISP_WIDTH - x;
+    }
+
+    if( h > ( ( LCD_DISP_WIDTH / 2 ) * LCD_DISP_HEIGHT_MAX_BUF ) / ( w / 2 )  ) {
+        h = ( ( LCD_DISP_WIDTH / 2 ) * LCD_DISP_HEIGHT_MAX_BUF ) / ( w / 2 );
+    }
+
+    if( ( window_x == x )&&
+        ( window_y == y )&&
+        ( window_w == w )&&
+        ( window_h == h ) ) {
+        /* Same Area */
+        return;
+    }
+
+    window_x = x;
+    window_y = y;
+    window_w = w;
+    window_h = h;
+
+    /* Initialize Buffer */
+    memset( &disp_buf[0], (char)( (_background & 0x0F ) | ( (_background & 0x0F ) << 4 ) ), sizeof(disp_buf) );
+
+#endif /* ( LCD_DEVICE_HEIGHT != LCD_DISP_HEIGHT_MAX_BUF ) */
+
+    GraphicsDisplay::window( x, y, w, h );
+}
+
+
+/** Set a pixel on the window memory */
+void ColorMemLCD::pixel( int x, int y, int color )
+{
+    if( ( window_x > x )||
+        ( ( window_x + window_w ) <= x )||
+        ( window_y > y )||
+        ( ( window_y + window_h ) <= y ) ) {
+        /* out of display buffer */
+        return;
+    }
+
+    if( ( x % 2 ) == 0 ) {
+        disp_buf[ ( (window_w / 2) * ( y - window_y ) ) + ( ( x - window_x ) / 2 ) ] &= 0x0F;
+        disp_buf[ ( (window_w / 2) * ( y - window_y ) ) + ( ( x - window_x ) / 2 ) ] |= ( ( color & 0x0F ) << 4 );
+    }
+    else {
+        disp_buf[ ( (window_w / 2) * ( y - window_y ) ) + ( ( x - window_x ) / 2 ) ] &= 0xF0;
+        disp_buf[ ( (window_w / 2) * ( y - window_y ) ) + ( ( x - window_x ) / 2 ) ] |= ( ( color & 0x0F )      );
+    }
+}
+
+
+/** Set a pixel - for transrucent mode */
+void ColorMemLCD::pixel_alpha( int x, int y, int color )
+{
+    if( ( window_x > x )||
+        ( ( window_x + window_w ) <= x )||
+        ( window_y > y )||
+        ( ( window_y + window_h ) <= y ) ) {
+        /* out of display buffer */
+        return;
+    }
+
+    if( ( x % 2 ) == 0 ) {
+        disp_buf[ ( (window_w / 2) * ( y - window_y ) ) + ( ( x - window_x ) / 2 ) ] &= ( ( ( color & 0x0F ) << 4 ) | 0x0F );
+    }
+    else {
+        disp_buf[ ( (window_w / 2) * ( y - window_y ) ) + ( ( x - window_x ) / 2 ) ] &= ( ( ( color & 0x0F )      ) | 0xF0 );
+    }
+}
+
+
+/** Fill the window memory with background color */
+void ColorMemLCD::cls( void )
+{
+    memset( &disp_buf[0], (char)( (_background & 0x0F ) | ( (_background & 0x0F ) << 4 ) ), sizeof(disp_buf) );
+}
+
+
+/** draw a circle */
+void ColorMemLCD::circle( int x0, int y0, int r, int color )
+{
+    int x = -r;
+    int y = 0;
+    int err = 2 - (2*r);
+    int e2 = err;
+
+    do {
+        pixel( x0-x, y0+y, color );
+        pixel( x0+x, y0+y, color );
+        pixel( x0+x, y0-y, color );
+        pixel( x0-x, y0-y, color );
+        e2 = err;
+        if( e2 <= y ) {
+            err += ( ( ++y ) * 2 ) + 1;
+            if( ( -x == y )&&( e2 <= x ) ) {
+                e2 = 0;
+            }
+        }
+        if( e2 > x ) {
+            err += ( ( ++x ) * 2 ) + 1;
+        }
+    } while (x <= 0);
+}
+
+
+/** draw a filled circle */
+void ColorMemLCD::fillcircle( int x0, int y0, int r, int color )
+{
+    int x = -r;
+    int y = 0;
+    int err = 2 - (2*r);
+    int e2 = err;
+
+    do {
+        vline( x0-x, y0-y, y0+y, color );
+        vline( x0+x, y0-y, y0+y, color );
+        e2 = err;
+        if( e2 <= y ) {
+            err += ( ( ++y ) * 2 ) + 1;
+            if( ( -x == y )&&( e2 <= x ) ) {
+                e2 = 0;
+            }
+        }
+        if( e2 > x ) {
+            err += ( ( ++x ) * 2 ) + 1;
+        }
+    } while (x <= 0);
+}
+
+
+/** draw a horizontal line */
+void ColorMemLCD::hline( int x0, int x1, int y, int color )
+{
+    int x;
+    int direction;
+
+    if( x0 == x1 ) {
+        pixel( x0, y, color );
+        return;
+    }
+    else if( x0 > x1 ) {
+        direction = -1;
+    }
+    else {
+        direction = 1;
+    }
+
+    for( x = x0 ; x <= x1 ; x += direction ) {
+        pixel( x, y, color );
+    }
+}
+
+
+/** draw a vertical line */
+void ColorMemLCD::vline( int x, int y0, int y1, int color )
+{
+    int y;
+    int direction;
+
+    if( y0 == y1 ) {
+        pixel( x, y0, color );
+        return;
+    }
+    else if( y0 > y1 ) {
+        direction = -1;
+    }
+    else {
+        direction = 1;
+    }
+
+    for( y = y0 ; y <= y1 ; y += direction ) {
+        pixel( x, y, color );
+    }
+}
+
+
+/** draw a 1 pixel line */
+void ColorMemLCD::line( int x0, int y0, int x1, int y1, int color )
+{
+    int dx = 0;
+    int dy = 0;
+    int dx_sym = 0;
+    int dy_sym = 0;
+    int dx_x2 = 0;
+    int dy_x2 = 0;
+    int di = 0;
+
+    dx = x1 - x0;
+    dy = y1 - y0;
+
+    if( dx == 0 ) {        /* vertical line */
+        vline( x0, y0, y1, color );
+        return;
+    }
+    else if( dx > 0 ) {
+        dx_sym = 1;
+    }
+    else {
+        dx_sym = -1;
+    }
+
+    if( dy == 0 ) {        /* horizontal line */
+        hline( x0, x1, y0, color );
+        return;
+    }
+    else if( dy > 0 ) {
+        dy_sym = 1;
+    }
+    else {
+        dy_sym = -1;
+    }
+
+    dx = dx_sym * dx;
+    dy = dy_sym * dy;
+
+    dx_x2 = dx * 2;
+    dy_x2 = dy * 2;
+
+    if( dx >= dy ) {
+        di = dy_x2 - dx;
+        while ( x0 != x1 ) {
+
+            pixel( x0, y0, color );
+            x0 += dx_sym;
+            if( di < 0 ) {
+                di += dy_x2;
+            }
+            else {
+                di += dy_x2 - dx_x2;
+                y0 += dy_sym;
+            }
+        }
+        pixel( x0, y0, color );
+    }
+    else {
+        di = dx_x2 - dy;
+        while( y0 != y1 ) {
+            pixel( x0, y0, color );
+            y0 += dy_sym;
+            if( di < 0 ) {
+                di += dx_x2;
+            }
+            else {
+                di += dx_x2 - dy_x2;
+                x0 += dx_sym;
+            }
+        }
+        pixel( x0, y0, color );
+    }
+    return;
+}
+
+
+/** draw a rect */
+void ColorMemLCD::rect( int x0, int y0, int x1, int y1, int color )
+{
+    hline( x0, x1, y0, color );
+
+    vline( x0, y0, y1, color );
+
+    hline( x0, x1, y1, color );
+
+    vline( x1, y0, y1, color );
+}
+
+
+/** draw a filled rect */
+void ColorMemLCD::fillrect(int x0, int y0, int x1, int y1, int color)
+{
+    int y;
+    int direction;
+
+    if( y0 == y1 ) {
+        hline( x0, x1, y0, color );
+        return;
+    }
+    else if( y0 > y1 ) {
+        direction = -1;
+    }
+    else {
+        direction = 1;
+    }
+
+    for( y = y0 ; y <= y1 ; y += direction ) {
+        hline( x0, x1, y, color );
+    }
+}
+
+
+/** setup cursor position */
+void ColorMemLCD::locate( int x, int y )
+{
+    char_x = x;
+    char_y = y;
+}
+
+
+/** calculate the max number of char in a line */
+int ColorMemLCD::columns()
+{
+    return width() / font[1];
+}
+
+
+/** calculate the max number of columns */
+int ColorMemLCD::rows()
+{
+    return height() / font[2];
+}
+
+
+/** put a char on the screen */
+int ColorMemLCD::_putc( int value )
+{
+    if( value == '\n' ) {    // new line
+        char_x = 0;
+        char_y = char_y + font[2];
+        if( char_y >= ( height() - font[2] ) ) {
+            char_y = 0;
+        }
+    } else {
+        character( char_x, char_y, value );
+    }
+    return value;
+}
+
+
+/** draw a character of selected font */
+void ColorMemLCD::character( int x, int y, int c )
+{
+    int hor, vert, offset, bpl, j, i, b;
+    unsigned char* zeichen;
+    unsigned char z,w;
+
+    if( (c < 31) || (c > 127) ) {
+        return;   // test char range
+    }
+
+    // read font parameter from start of array
+    offset  = font[0];          // bytes / char
+    hor     = font[1];          // get hor size of font
+    vert    = font[2];          // get vert size of font
+    bpl     = font[3];          // bytes per line
+
+    if( char_x + hor > width() ) {
+        char_x = 0;
+        char_y = char_y + vert;
+        if( char_y >= height() - vert ) {
+            char_y = 0;
+        }
+    }
+    zeichen = &font[ ( ( c - 32 ) * offset ) + 4 ]; // start of char bitmap
+    w = zeichen[0];                                 // width of actual char
+    for( j = 0; j < vert ; j++ ) {                  //  vert line
+        for( i = 0 ; i < hor ; i++ ) {              //  horz line
+            z =  zeichen[ bpl * i + ( ( j & 0xF8 ) >> 3 ) + 1 ];
+            b = 1 << ( j & 0x07 );
+            if( ( z & b ) == 0x00 ) {
+                if( trans_mode == LCD_TRANSMODE_OPAQUE ) {
+                    pixel( x + i, y + j, _background );
+                }
+                else if( trans_mode == LCD_TRANSMODE_TRANSLUCENT ) {
+                    pixel_alpha( x + i, y + j, _background );
+                }
+            } else {
+                pixel( x + i, y + j, _foreground );
+            }
+        }
+    }
+    if( ( w + 2 ) < hor ) {                         // x offset to next char
+        char_x += w + 2;
+    }
+    else {
+        char_x += hor;
+    }
+}
+
+/** draw a symbol of same format as "character"  */
+void ColorMemLCD::symbol(unsigned int x, unsigned int y, unsigned char *symbol)
+{
+    unsigned int hor,vert,bpl,j,i,b; 
+    unsigned char z;
+    
+    hor = symbol[0];                       // get hor size of font
+    vert = symbol[1];                      // get vert size of font
+    bpl = symbol[2];                       // bytes per line
+
+    if( char_x + hor > width() ) {
+        char_x = 0;
+        char_y = char_y + vert;
+        if( char_y >= height() - vert ) {
+            char_y = 0;
+        }
+    }
+
+    for( j = 0; j < vert ; j++ ) {                  //  vert line
+        for( i = 0 ; i < hor ; i++ ) {              //  horz line
+            z =  symbol[ bpl * i + ( ( j & 0xF8 ) >> 3 ) + 1 + 3 ];
+            b = 1 << ( j & 0x07 );
+            if( ( z & b ) == 0x00 ) {
+                if( trans_mode == LCD_TRANSMODE_OPAQUE ) {
+                    pixel( x + i, y + j, _background );
+                }
+                else if( trans_mode == LCD_TRANSMODE_TRANSLUCENT ) {
+                    pixel_alpha( x + i, y + j, _background );
+                }
+            } else {
+                pixel( x + i, y + j, _foreground );
+            }
+        }
+    }
+}
+
+
+/** select the font  */
+void ColorMemLCD::set_font( unsigned char* f )
+{
+    font = f;
+}
+
+
+/** set transpalent effect */
+void ColorMemLCD::setTransMode( char mode )
+{
+    trans_mode = mode;
+}
+
+
+/** set a bitmap on the window buffer */
+void ColorMemLCD::Bitmap4bit( int x, int y, int w, int h, unsigned char *bitmap )
+{
+    Bitmap4bit( x, y, w, h, bitmap, 0, 0, w, h );
+}
+
+
+/** set a bitmap on the window buffer  */
+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 )
+{
+    int i, j;
+
+    if( ( x         < 0 )||
+        ( y         < 0 )||
+        ( w         <= 0 )||
+        ( h         <= 0 )||
+        ( bitmap == NULL )||
+        ( bmp_x     < 0 )||
+        ( bmp_y     < 0 )||
+        ( bmp_w     <= 0 )||
+        ( bmp_h     <= 0 )||
+        ( ( x       & 0x01 ) == 0x01 )||
+        ( ( w       & 0x01 ) == 0x01 )||
+        ( ( bmp_x   & 0x01 ) == 0x01 )||
+        ( ( bmp_w   & 0x01 ) == 0x01 ) ) {
+        /* Parameter Error */
+        return;
+    }
+
+    for( i = 0 ; i < h ; i++ ) {
+        if( ( window_y > i + y )||
+            ( ( window_y + window_h ) <= i + y )||
+            ( ( bmp_h ) <= i + bmp_y ) ) {
+            /* out of display buffer */
+            continue;
+        }
+        for( j = 0 ; j < w ; j += 2 ) {
+            if( ( window_x > j + x )||
+                ( ( window_x + window_w ) <= j + x )||
+                ( ( bmp_w ) <= j + bmp_x ) ) {
+                /* out of display buffer */
+                continue;
+            }
+            /* copy to display bufffer */
+            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 ) ];
+        }
+    }
+}
+
+
+/** set a bitmap on the window buffer */
+void ColorMemLCD::Bitmap1bit( int x, int y, int w, int h, unsigned char *bitmap )
+{
+    Bitmap1bit( x, y, w, h, bitmap, 0, 0, w, h );
+}
+
+
+/** set a bitmap on the window buffer  */
+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 )
+{
+    int i, j;
+    int byte, offset;
+
+    if( ( x         < 0 )||
+        ( y         < 0 )||
+        ( w         <= 0 )||
+        ( h         <= 0 )||
+        ( bitmap == NULL )||
+        ( bmp_x     < 0 )||
+        ( bmp_y     < 0 )||
+        ( bmp_w     <= 0 )||
+        ( bmp_h     <= 0 ) ) {
+        /* Parameter Error */
+        return;
+    }
+
+    for( i = 0 ; i < h ; i++ ) {
+        if( ( window_y > i + y )||
+            ( ( window_y + window_h ) <= i + y )||
+            ( ( bmp_h ) <= i + bmp_y ) ) {
+            /* out of display buffer */
+            continue;
+        }
+        for( j = 0 ; j < w ; j ++ ) {
+            if( ( window_x > j + x )||
+                ( ( window_x + window_w ) <= j + x )||
+                ( ( bmp_w ) <= j + bmp_x ) ) {
+                /* out of display buffer */
+                continue;
+            }
+            byte    = ( ( bmp_w * ( i + bmp_y ) ) + ( ( j + bmp_x ) ) ) / 8;
+            offset  = ( ( bmp_w * ( i + bmp_y ) ) + ( ( j + bmp_x ) ) ) % 8;
+            /* set to display bufffer */
+            if( ( bitmap[ byte ] & ( 0x80 >> offset ) ) != 0x00 ) {
+                /* Foregroud */
+                pixel( ( j + x - window_x ), ( i + y - window_y ), _foreground );
+            }
+            else {
+                /* Backgroud */
+                if( trans_mode == LCD_TRANSMODE_OPAQUE ) {
+                    pixel( ( j + x - window_x ), ( i + y - window_y ), _background );
+                }
+                else if( trans_mode == LCD_TRANSMODE_TRANSLUCENT ) {
+                    pixel_alpha( ( j + x - window_x ), ( i + y - window_y ), _background );
+                }
+            }
+        }
+    }
+}
+
+
+/** Transfer to the LCD from diaply buffer */
+void ColorMemLCD::update()
+{
+    int32_t         i;
+    int    copy_width;
+
+    if( window_x + window_w < LCD_DISP_WIDTH ) {
+        copy_width = (window_w / 2);
+    }
+    else {
+        copy_width = ( ( LCD_DISP_WIDTH - window_x ) / 2 );
+    }
+
+    for( i = 0 ; i < window_h ; i++ ) {
+
+        if( window_y + i > LCD_DISP_HEIGHT ){
+            /* out of window system */
+            break;
+        }
+
+        /* initialize command buffer */
+        memset( &cmd_buf[0], (char)( (_background & 0x0F ) | ( (_background & 0x0F ) << 4 ) ), sizeof(cmd_buf) );
+
+        /* copy to command bufffer */
+        memcpy( &cmd_buf[(window_x/2)], &disp_buf[ (window_w / 2) * i ], copy_width );
+
+        /* send cmaoond request */
+        sendLineCommand( &cmd_buf[0], window_y + i );
+    }
+}
+
+
+/** Transfer a 24 bit BMP to the LCD from filesytem */
+int ColorMemLCD::BMP_24( int x,  int y, const char *filenameBMP )
+{
+    FILE*       fp;
+    int32_t     width;
+    int32_t     height;
+    int16_t     data_bit_size;
+    bool        data_direction = false; 
+//  uint32_t    filesize;
+    uint32_t    data_offset;
+    int32_t     i = 0;
+    int32_t     j = 0;
+    int32_t     line = 0;
+
+    memset( &file_buf[0], 0, sizeof(file_buf) );
+
+    fp = fopen( filenameBMP, "rb" );
+    if( fp != NULL ) {
+        /* read file header */
+        fread( &file_buf[0], sizeof(char), 14, fp );
+
+//      filesize    = file_buf[ 2] + ( file_buf[ 3] << 8 ) +  ( file_buf[ 4] << 16 ) +  ( file_buf[ 5] << 24 );
+        data_offset = file_buf[10] + ( file_buf[11] << 8 ) +  ( file_buf[12] << 16 ) +  ( file_buf[13] << 24 );
+
+        if( data_offset <= 14 ) {
+            /* error */
+            fclose(fp);
+            return(0);
+        }
+
+        memset( &file_buf[0], 0, sizeof(file_buf) );
+
+        /* read file header */
+        fread( &file_buf[0], sizeof(char), (data_offset - 14), fp );
+
+        if( data_offset == 0x0C ) {
+            /* OS/2 format */
+            width       = file_buf[ 4] + ( file_buf[ 5] << 8 );
+            height      = file_buf[ 6] + ( file_buf[ 7] << 8 );
+            data_bit_size   = file_buf[10] + ( file_buf[11] << 8 );
+        }
+        else if( data_offset == 0x36 ){
+            /* Windows format */
+            width       = file_buf[ 4] + ( file_buf[ 5] << 8 ) + ( file_buf[ 6] << 16 ) + ( file_buf[ 7] << 24 );
+            height      = file_buf[ 8] + ( file_buf[ 9] << 8 ) + ( file_buf[10] << 16 ) + ( file_buf[11] << 24 );
+            data_bit_size   = file_buf[14] + ( file_buf[15] << 8 );
+        }
+        else{
+            /* Unknown format */
+            fclose(fp);
+            return(0);
+        }
+
+        if( data_bit_size != 24 ) {
+            /* Not 24bit format */
+            fclose(fp);
+            return(0);
+        }
+
+        if( height < 0 ) {
+            height *= -1;
+            data_direction = true;
+        }
+
+        if( data_direction == true ) {
+            line = i;
+        }
+        else {
+            line = height - i - 1;
+        }
+
+        for( i = 0; i < height; i++ ) {
+
+            if( data_direction == true ) {
+                line = i + y;
+            }
+            else {
+                line = height - i - 1 + y;
+            }
+            if( line >= LCD_DISP_HEIGHT ) {
+                /* out of window system */
+                continue;
+            }
+
+            /* initialize line display data with backgroud color */
+            memset( &cmd_buf[0], (char)( (_background & 0x0F ) | ( (_background & 0x0F ) << 4 ) ), sizeof(cmd_buf) );
+
+            if( ( line > window_y )&&
+                ( line < window_y + window_h ) ) {
+                /* inside display_buffer */
+                memcpy( &cmd_buf[ ( window_x / 2 ) ], &disp_buf[ ( window_w / 2 ) * ( line - window_y ) ], ( window_w / 2 ) );
+            }
+
+            for( j = 0 ; j < width / 2 ; j++ ) {
+                /* Read pixel */
+                memset( &file_buf[0], 0, 6 );
+                if( ( ( j * 2 ) + 1 ) < width ) {
+                    fread( &file_buf[0], sizeof(char), 6, fp );
+                }
+                else if( ( ( j * 2 ) + 1 ) == width ){
+                    fread( &file_buf[0], sizeof(char), 3, fp );
+                }
+                else {
+                    break;
+                }
+                if( j + ( x / 2 ) >= (LCD_DISP_WIDTH/2) ) {
+                    /* out of window system */
+                    continue;
+                }
+                cmd_buf[ j + ( x / 2 ) ]  = ( ( file_buf[0] & 0x80 ) >> 2 );   /* B */
+                cmd_buf[ j + ( x / 2 ) ] |= ( ( file_buf[1] & 0x80 ) >> 1 );   /* G */
+                cmd_buf[ j + ( x / 2 ) ] |=   ( file_buf[2] & 0x80 );          /* R */
+
+                if( ( ( j * 2 ) + 1 ) < width ) {
+                    cmd_buf[ j + ( x / 2 ) ] |= ( ( file_buf[3] & 0x80 ) >> 6 );   /* B */
+                    cmd_buf[ j + ( x / 2 ) ] |= ( ( file_buf[4] & 0x80 ) >> 5 );   /* G */
+                    cmd_buf[ j + ( x / 2 ) ] |= ( ( file_buf[5] & 0x80 ) >> 4 );   /* R */
+                }
+            }
+
+            /* send cmaoond request */
+            sendLineCommand( &cmd_buf[0], line );
+
+            /* copy to display buffer */
+            if( ( line > window_y )&&
+                ( line < window_y + window_h ) ) {
+                /* inside display_buffer */
+                memcpy( &disp_buf[ ( window_w / 2 ) * ( line - window_y ) ], &cmd_buf[ ( window_x / 2 ) ], ( window_w / 2 ) );
+            }
+        }
+        fclose(fp);
+    }
+
+    return(1);
+}
+
+
+/** send data packet */
+void ColorMemLCD::sendLineCommand( char* line_cmd, int line  )
+{
+    int i;
+    int32_t j;
+
+    if( ( line < 0 )||
+        ( line >= LCD_DEVICE_HEIGHT ) ) {
+        /* out of device size */
+        return;
+    }
+
+    wait_us(6);
+    _cs = 1;
+    wait_us(6);
+    _spi.write( LCD_COLOR_CMD_UPDATE | ( polarity << 6 ) ); // Command
+    _spi.write( line + 1 );             // line
+
+    for( j = 0 ; j < (LCD_DISP_WIDTH/2) ; j++ ) {
+        if( j >= (LCD_DEVICE_WIDTH/2) ) {
+            /* out of device size */
+            break;
+        }
+        _spi.write(line_cmd[j]);        // data
+    }
+    for( ; j < (LCD_DEVICE_WIDTH/2) ; j++ ) {
+        /* padding to device size */
+        _spi.write( 0x00 );
+    }
+
+    _spi.write( 0x00 );
+    _spi.write( 0x00 );
+    wait_us(6);
+    _cs = 0;
+}
+
+
+/** Toggle the polarity at evry scecond */
+void ColorMemLCD::polling()
+{
+    if( polarity == 0 ) {
+        polarity = 1;
+    }
+    else {
+        polarity = 0;
+    }
+
+    if( _cs == 1 ) {
+        return;
+    }
+
+    command_SetState();
+}
+
+
+/** Command for setting the state of LCD */
+void ColorMemLCD::command_SetState()
+{
+    wait_us( 6 );
+    _cs = 1;
+    wait_us( 6 );
+    _spi.write( blink_cmd | ( polarity << 6 ));
+    _spi.write( 0x00 );
+    wait_us(6);
+    _cs = 0;
+}
+
+
+/** Command to clear whole the LCD */
+void ColorMemLCD::command_AllClear()
+{
+    wait_us( 6 );
+    _cs = 1;
+    wait_us( 6 );
+    _spi.write( LCD_COLOR_CMD_ALL_CLEAR | ( polarity << 6 ));
+    _spi.write( 0x00 );
+    wait_us(6);
+    _cs = 0;
+}
+
+
+/** Command to blink */
+void ColorMemLCD::setBlinkMode( char mode )
+{
+    switch( mode ) {
+        case LCD_BLINKMODE_NONE:
+            /* Blinking None    */
+            blink_cmd = LCD_COLOR_CMD_NO_UPDATE;
+            break;
+        case LCD_BLINKMODE_WHITE:
+            /* Blinking White   */
+            blink_cmd = LCD_COLOR_CMD_BLINKING_WHITE;
+            break;
+        case LCD_BLINKMODE_BLACK:
+            /* Blinking Black   */
+            blink_cmd = LCD_COLOR_CMD_BLINKING_BLACK;
+            break;
+        case LCD_BLINKMODE_INVERSE:
+            /* Inversion Mode   */
+            blink_cmd = LCD_COLOR_CMD_INVERSION;
+            break;
+        default:
+            /* No Update */
+            blink_cmd = LCD_COLOR_CMD_NO_UPDATE;
+            break;
+    }
+
+    _cs = 1;
+    wait_us( 6 );
+    _spi.write( blink_cmd | ( polarity << 6 ));
+    _spi.write( 0x00 );
+    wait_us(6);
+    _cs = 0;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ColorMemLCD.h	Thu Jun 23 02:08:18 2016 +0000
@@ -0,0 +1,375 @@
+/*
+ * mbed library for the JDI color memory LCD LPM013M126A
+ * derived from C12832_lcd
+ * Copyright (c) 2016  Tadayuki Okamoto 
+ * Released under the MIT License: http://mbed.org/license/mit
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+ 
+#ifndef MBED_COLOR_MEM_LCD_H
+#define MBED_COLOR_MEM_LCD_H
+
+#include "mbed.h"
+#include "GraphicsDisplay.h"
+
+
+/** @def
+ * Device define
+ */
+#define LCD_DEVICE_WIDTH        (176)
+#define LCD_DEVICE_HEIGHT       (176)
+
+/** @def
+ * window system define
+ */
+#define LCD_DISP_WIDTH          (176)
+#define LCD_DISP_HEIGHT         (176)
+#define LCD_DISP_HEIGHT_MAX_BUF (44)
+
+
+/** @def
+ * some RGB color definitions
+ */
+/*                                        R, G, B     */
+#define LCD_COLOR_BLACK     (0x00)    /*  0  0  0  0  */
+#define LCD_COLOR_BLUE      (0x02)    /*  0  0  1  0  */
+#define LCD_COLOR_GREEN     (0x04)    /*  0  1  0  0  */
+#define LCD_COLOR_CYAN      (0x06)    /*  0  1  1  0  */
+#define LCD_COLOR_RED       (0x08)    /*  1  0  0  0  */
+#define LCD_COLOR_MAGENTA   (0x0a)    /*  1  0  1  0  */
+#define LCD_COLOR_YELLOW    (0x0c)    /*  1  1  0  0  */
+#define LCD_COLOR_WHITE     (0x0e)    /*  1  1  1  0  */
+
+/** @def
+ * ID for setTransMode
+ */
+#define LCD_TRANSMODE_OPAQUE        (0x00)  //!< BackGroud is Opaque
+#define LCD_TRANSMODE_TRANSPARENT   (0x01)  //!< BackGroud is Transparent
+#define LCD_TRANSMODE_TRANSLUCENT   (0x02)  //!< BackGroud is Translucent
+
+/** @def
+ *ID for setBlinkMode
+ */
+#define LCD_BLINKMODE_NONE      (0x00)  //!< Blinking None
+#define LCD_BLINKMODE_WHITE     (0x01)  //!< Blinking White
+#define LCD_BLINKMODE_BLACK     (0x02)  //!< Blinking Black
+#define LCD_BLINKMODE_INVERSE   (0x03)  //!< Inversion Mode
+
+/** A class for Color Memory LCD Library
+*/
+class ColorMemLCD : public GraphicsDisplay {
+    public:
+
+    /** Create a SPI_LCD object connected to SPI
+     *
+     * @param mosi pin connected to SDO of display
+     * @param miso pin connected to SDI of display
+     * @param sclk pin connected to RS of display 
+     * @param cs pin connected to CS of display
+     * @param disp pin connected to DISP of display
+     * @param power pin connected to POWER of display
+     */
+    ColorMemLCD( PinName mosi, PinName miso, PinName sclk, PinName cs, PinName disp, PinName power, const char* name ="TFT" );
+
+    /** Get the width of the screen in pixel
+     *
+     * @return width of screen in pixel
+     *
+     */
+    virtual int width();
+
+    /** Get the height of the screen in pixel
+     *
+     * @return height of screen in pixel 
+     *
+     */
+    virtual int height();
+
+    /** Set window region
+     *
+     * @param x horizontal position
+     * @param y vertical position
+     * @param w window width in pixel
+     * @param h window height in pixels
+     */
+    virtual void window( int x, int y, int w, int h );
+
+    /** Set a pixel on the window memory
+     *  
+     * @param x horizontal position
+     * @param y vertical position
+     * @param color 4 bit pixel color
+     */
+    virtual void pixel(int x, int y,int colour);
+
+    /** Set a pixel on the window memory (alpha blend)
+     *  
+     * @param x horizontal position
+     * @param y vertical position
+     * @param color 4 bit pixel color
+     */
+    virtual void pixel_alpha(int x, int y,int colour);
+
+    /** Fill the window memory with background color
+     *
+     */
+    virtual void cls (void);
+
+    /** draw a circle
+     *
+     * @param x0,y0 center
+     * @param r radius
+     * @param color 4 bit color
+     *
+     */
+    void circle(int x, int y, int r, int colour); 
+
+    /** draw a filled circle
+     *
+     * @param x0,y0 center
+     * @param r radius
+     * @param color 4 bit color
+     */
+    void fillcircle(int x, int y, int r, int colour); 
+
+    /** draw a horizontal line
+     *
+     * @param x0 horizontal start
+     * @param x1 horizontal stop
+     * @param y vertical position
+     * @param color 4 bit color
+     *
+     */
+    void hline(int x0, int x1, int y, int colour);
+
+    /** draw a vertical line
+     *
+     * @param x horizontal position
+     * @param y0 vertical start 
+     * @param y1 vertical stop
+     * @param color 4 bit color
+     */
+    void vline(int y0, int y1, int x, int colour);
+
+    /** draw a 1 pixel line
+     *
+     * @param x0,y0 start point
+     * @param x1,y1 stop point
+     * @param color 4 bit color
+     *
+     */
+    void line(int x0, int y0, int x1, int y1, int colour);
+
+    /** draw a rect
+     *
+     * @param x0,y0 top left corner
+     * @param x1,y1 down right corner
+     * @param color 4 bit color
+     *
+     */
+    void rect(int x0, int y0, int x1, int y1, int colour);
+
+    /** draw a filled rect
+     *
+     * @param x0,y0 top left corner
+     * @param x1,y1 down right corner
+     * @param color 4 bit color
+     *
+     */
+    void fillrect(int x0, int y0, int x1, int y1, int colour);
+
+    /** setup cursor position
+     *
+     * @param x x-position (top left)
+     * @param y y-position 
+     */
+    virtual void locate(int x, int y);
+
+    /** calculate the max number of char in a line
+     *
+     * @return max columns depends on actual font size
+     *
+     */
+    virtual int columns(void);
+
+    /** calculate the max number of columns
+     *
+     * @return max columndepends on actual font size
+     *
+     */
+    virtual int rows(void);
+
+    /** put a char on the screen
+     *
+     * @param value char to print
+     * @return printed char
+     *
+     */
+    virtual int _putc(int value);
+
+    /** draw a character of selected font
+     *
+     * @param x x-position of char (top left) 
+     * @param y y-position
+     * @param c char to print
+     *
+     */
+    virtual void character(int x, int y, int c);
+    
+    /** select the font
+     *
+     * @param f pointer to font array 
+     *
+     */
+    void set_font(unsigned char* f);
+
+    /** set transpalent effect
+     *
+     * @param mode trans mode
+     *
+     */
+    void setTransMode( char mode );
+
+    /** set a bitmap on the window buffer
+     *
+     * @param x,y upper left corner 
+     * @param w width of bitmap
+     * @param h high of bitmap
+     * @param *bitmap pointer to the bitmap data
+     *
+     * @remarks bitmap format 4 bit R1 G1 B1
+     * 
+     */
+    void Bitmap4bit( int x, int y, int w, int h, unsigned char *bitmap);
+
+    /** set a bitmap on the window buffer
+     *
+     * @param x,y upper left corner 
+     * @param w width of draw rect
+     * @param h high of draw rect
+     * @param *bitmap pointer to the bitmap data
+     * @param bmp_x,bmp_y upper left corner at BMP files
+     * @param bmp_w width of bitmap
+     * @param bmp_h high of bitmap
+     *
+     * @remarks bitmap format 4 bit R1 G1 B1
+     * 
+     */
+    void Bitmap4bit( int x, int y, int w, int h, unsigned char *bitmap, int bmp_x, int bmp_y, int bmp_w, int bmp_h );
+
+    /** set a bitmap on the window buffer
+     *
+     * @param x,y upper left corner 
+     * @param w width of bitmap
+     * @param h high of bitmap
+     * @param *bitmap pointer to the bitmap data
+     *
+     * @remarks bitmap format 1 bit
+     * 
+     */
+    void Bitmap1bit( int x, int y, int w, int h, unsigned char *bitmap);
+
+    /** set a bitmap on the window buffer
+     *
+     * @param x,y upper left corner 
+     * @param w width of draw rect
+     * @param h high of draw rect
+     * @param *bitmap pointer to the bitmap data
+     * @param bmp_x,bmp_y upper left corner at BMP files
+     * @param bmp_w width of bitmap
+     * @param bmp_h high of bitmap
+     *
+     * @remarks bitmap format 1 bit
+     * 
+     */
+    void Bitmap1bit( int x, int y, int w, int h, unsigned char *bitmap, int bmp_x, int bmp_y, int bmp_w, int bmp_h );
+
+    /** Transfer to the LCD from diaply buffer
+     * 
+     */
+    void update();
+
+    /** Transfer a 24 bit BMP to the LCD from filesytem
+     *
+     * @param x,y position of upper left corner 
+     * @param *filenameBMP name of the BMP file
+     *
+     * @retval 1 succes
+     * @retval 0 error
+     *
+     * @remarks bitmap format 24 bit R8 G8 B8
+     * 
+     */
+    int BMP_24( int x,  int y, const char *filenameBMP );
+
+    /** Command for setting the state of LCD
+     *
+     */
+    void command_SetState();
+
+    /** Command to clear whole the LCD
+     *
+     */
+    void command_AllClear();
+
+    /** Command to blink
+     * @param mode Blinking Mode or Inversion Mode
+     *
+     */
+    void setBlinkMode( char mode );
+
+    /** Toggle the LCD polarity 
+     *
+     */
+    void polling();
+
+    void symbol(unsigned int x, unsigned int y, unsigned char *symbol);
+
+protected:
+
+    /* Instance of inteface */
+    SPI         _spi;
+    DigitalOut _cs; 
+    DigitalOut _disp;
+    DigitalOut _power;
+
+    /* polarity variable */
+    char        polarity;
+    char        blink_cmd;
+
+    /* trans mode variable */
+    char        trans_mode;
+
+    /* data for character variable */
+    unsigned char* font;
+    int char_x;
+    int char_y;
+
+    /* window  variable */
+    int window_x;
+    int window_y;
+    int window_w;
+    int window_h;
+
+    /* temporary buffer */
+    char    cmd_buf[LCD_DISP_WIDTH/2];                              /* for sending command */
+    char    disp_buf[(LCD_DISP_WIDTH/2)*LCD_DISP_HEIGHT_MAX_BUF];   /* display buffer */
+    char    file_buf[118];                                          /* for reading files */
+
+    /** send command
+     *
+     * @param line_cmd cmannd data
+     * @param line line of display
+     *
+     */
+    void sendLineCommand( char* line_cmd, int line );
+};
+
+#endif /* MBED_COLOR_MEM_LCD_H */