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
diff -r 000000000000 -r 76a4e97c113f ColorMemLCD.cpp
--- /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
Tadayuki Okamoto
JDI Color Memory LCD