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.
Diff: ColorMemLCD.cpp
- Revision:
- 0:76a4e97c113f
- Child:
- 1:b035a997ec3f
--- /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