Version 6.0. Animaiton demo.

Dependents:   MIP8f_FRDM_Animation_sample

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MIP8F_SPI.cpp Source File

MIP8F_SPI.cpp

Go to the documentation of this file.
00001 /**
00002 * @file MIP8F_SPI.cpp
00003 * @brief ver5.0 Library source code file: Class for JDI MIP8 display
00004 * @details
00005 * Ver5.0 Addtional function is checking the refresh display speed between 4bit,3bit and 1bit transfer mode 
00006 * Ver4.0 Addtional function is Line buffer version
00007 * Ver3.0 Addtional function is font display
00008 * ver2.0 Addtional function is Monochome display by 1bit mode of SPI transfer.
00009 *
00010 * spi-transfer to Display has 3 mode. 
00011 * 4bit mode is color display, this bit arrange is  R,G,B,x.   R,G,B = R,G,B subpixel bit. x bit is Dummy.
00012 * 3bit mode is color display, this bit arrange is  R,G,B.   R,G,B = R,G,B subpixel bit.  No bit is Dummy.
00013 * 1bit mode is monocrome display,high speed refresh mode. a only Green subpixel of bitmap data is transfered.
00014 *
00015 * <license>
00016 * Copyright 2018 Japan Display Inc.
00017 * Licensed under the Apache License, Version 2.0 (the "License");
00018 * you may not use this file except in compliance with the License.
00019 * You may obtain a copy of the License at
00020 *     http://www.apache.org/licenses/LICENSE-2.0
00021 * Unless required by applicable law or agreed to in writing, software
00022 * distributed under the License is distributed on an "AS IS" BASIS,
00023 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00024 * See the License for the specific language governing permissions and
00025 * limitations under the License.
00026 */
00027 
00028 #include "mbed.h"
00029 #include "MIP8F_SPI.h"
00030 
00031 // for debug
00032 Serial pc2(USBTX, USBRX); // tx, rx
00033 
00034 memLCD8::memLCD8(PinName mosi,PinName miso,PinName sclk,PinName cs,PinName disp,PinName power)
00035     : _spi(mosi, miso, sclk),_cs(cs),_disp(disp),_power(power)
00036 {
00037 
00038     _power= 0;
00039     _disp=  0;
00040     _cs  =  0;
00041     wait_us(100);
00042 
00043     _power= 1;
00044     _spi.format(8,0);                // 8bit mode3
00045     _spi.frequency(2000000);         // 2 Mhz SPI clock
00046     _spi.write(0x00);                // mbed dummy
00047 
00048     /*
00049         _cs  = 1;
00050         command(0x02);   // All crear mode
00051         _cs  = 0;
00052     */
00053     _FixedFontWidth=0;//setting:actual font width display  if _FixedFontWidth !=1: font fixed witdh
00054 #if MOVIEBUFF_MODE    
00055     //movie_height = 80;
00056     //movie_width = 80;
00057     _height = 240;
00058     _width = 400;
00059 #endif
00060 }
00061 
00062 /**
00063 * @brief  set font name
00064 */
00065 void memLCD8::set_font(unsigned char* f)
00066 {
00067     font = f;
00068 }
00069 
00070 /**
00071 * @brief  set allocation for font display
00072 */
00073 void memLCD8::locate(int x, int y)
00074 {
00075     char_x = x;
00076     char_y = y;
00077 }
00078 
00079 /**
00080 * @brief  setting fixed width between charactor and charctor  for font display
00081 */
00082 void memLCD8::set_FixedFontWidth( unsigned char width )
00083 {
00084     _FixedFontWidth = width;
00085 }
00086 /**
00087 * @brief  setting Actual width between charactor and charctor  for font display
00088 */
00089 void memLCD8::set_ActualFontWidth(void)
00090 {
00091     _FixedFontWidth = 0;
00092 }
00093 
00094 /**
00095 * @brief  set Configuration for transfer mode
00096 * @param[in] int transfermode : instruction the transfer data size ,4bit,3bit,1bit and some parameter
00097 */
00098 void memLCD8::SetTransfermode(int transfermode)
00099 {
00100     switch(transfermode)
00101     {
00102     case TrBIT4:
00103         TrModeCommand = 0x90;
00104         TrAdd = 1;
00105         TrValNum = 1;
00106         break;
00107     case TrBIT3:
00108         TrModeCommand = 0x80;
00109         TrAdd = 4;
00110         TrValNum = 3;
00111         break;
00112     case TrBIT1:
00113         TrModeCommand = 0x88;
00114         TrAdd = 4;
00115         TrValNum = 1;
00116         break;
00117     }
00118 }
00119 
00120 /**
00121 * @brief  set a display size ,width ,height
00122 */
00123 void memLCD8::setWH(int width, int height)
00124 {
00125     _width  = width;
00126     _height = height;
00127 }
00128 
00129 /**
00130 * @brief  set color data of foreground
00131 */
00132 void memLCD8::foreground(uint8_t colour)
00133 {
00134     _foreground = colour;
00135 }
00136 
00137 /**
00138 * @brief  set color data of background
00139 */
00140 void memLCD8::background(uint8_t colour)
00141 {
00142     _background = colour;
00143 }
00144 
00145 /**
00146 * @brief  set the Diaplay On/Off data
00147 */
00148 void memLCD8::SwDisp(bool ONorOFF)
00149 {
00150     _disp= ONorOFF;
00151 }
00152 
00153 /**
00154 * @brief  transfer a command code to the display by SPI
00155 */
00156 void memLCD8::command(char command)
00157 {
00158     wait_us(6);
00159     _cs  = 1;
00160     wait_us(6);
00161     _spi.write(command);//
00162     _spi.write(0x00);// dummy
00163     wait_us(6);
00164     _cs  = 0;
00165 }
00166 
00167 /**
00168 * @brief  putc
00169 */
00170 int memLCD8::_putc(int value)
00171 {
00172     if (value == '\n') {    // new line
00173         char_x = 0;
00174         char_y = char_y + font[3];
00175         if (char_y >= _height - font[3]) {
00176             char_y = 0;
00177         }
00178     }
00179 #if FRAMEBUFF_MODE
00180      else {
00181         character(char_x, char_y, value);
00182     }
00183 #endif
00184     return value;
00185 }
00186 
00187 /**
00188 * @brief  getc
00189 */
00190 int memLCD8::_getc()
00191 {
00192     return -1;
00193 }
00194 /**
00195 * @brief  get color data of background
00196 */
00197 unsigned char memLCD8::get_Background(void)
00198 {
00199     return _background;
00200 }
00201 /*
00202 void memLCD8::setmarge(bool ifMarge)
00203 {
00204     _ifMarge = ifMarge;
00205 }
00206 */
00207 //////////////////////////////////////////////////////////////////////////////
00208 // line buffer mode
00209 //////////////////////////////////////////////////////////////////////////////
00210 #if LINEBUFF_MODE
00211 /**
00212 * @brief  Transfer One Pixel Data with x,y allocation Line buffer mode
00213 * @param[in] int x : horizontal allocation left to right
00214 * @param[in] uint8_t color : the color data for Drawing  0x0X  x is color data(RGBC) C is not used
00215 */
00216 void memLCD8::pixel(int x, uint8_t color)
00217 {
00218     if(!(x % 2)) _dispLINEBUF[x/2] =  _dispLINEBUF[x/2]&0x0F  |  (color << 4)&0xF0 ;   //MASK 0000 1111
00219     else         _dispLINEBUF[x/2] =  _dispLINEBUF[x/2]&0xF0  |  (color     )&0x0F ;   //MASK 1111 0000
00220 }
00221 
00222 /**
00223 * @brief  Transfer Pixel Data from same Line buffer to Display
00224 */
00225 void memLCD8::writeDISPLinebuffer(void)    // refresh whole display
00226 {
00227 
00228     char pol = 0;
00229     char command = 0x90; // 8b 1*0xNNNN *=POL x=AutoW  A  1010
00230 
00231     // frame
00232     for (int i=0; i<_height; i++) {
00233         // line
00234         wait_us(6);
00235         _cs  = 1;
00236         wait_us(6);
00237         _spi.write(command | (pol << 6) | (i+1)>>8 ); // COMMAND
00238         _spi.write((i+1)& 0x00FF ); // V ADDR
00239         for(int j=0; j<_width/2; j++) _spi.write(_dispLINEBUF[j]);
00240         _spi.write(0x00); // DUMMY transfer
00241         _spi.write(0x00); // DUMMY transfer
00242         wait_us(6);
00243         _cs  = 0;
00244         if(pol) pol=0x00;
00245         else    pol=0x01;
00246     }
00247 }
00248 
00249 /**
00250 * @brief  Transfer Pixel Data from line buffer to Display
00251 * @param[in] int line : set line number for display.
00252 * @param[in] int transfermode : instruction the transfer data size ,4bit,3bit,1bit
00253 */
00254 void memLCD8::writeDISP(int line,int transfermode)    // refresh gate line display
00255 {
00256 
00257     char pol = 0;
00258     //char command = 0x90; // 8b 1*0xNNNN *=POL x=AutoW  A  1010
00259     SetTransfermode(transfermode);
00260     
00261     // frame
00262         // line
00263         wait_us(6);
00264         _cs  = 1;
00265         wait_us(6);
00266         _spi.write(TrModeCommand | (pol << 6) | (line+1)>>8 ); // COMMAND
00267         //pc2.printf("com 0x%x\n",TrModeCommand | (pol << 6) | (i+1)>>8);
00268         
00269         _spi.write((line+1)& 0x00FF ); // V ADDR
00270         //pc2.printf("v adr 0x%x\n",(i+1)& 0x00FF);
00271         
00272         for(int j=0; j<_width; j+=TrAdd)
00273         {
00274             GetPixelValueFromLineBuffer(j,_dispLINEBUF);
00275             //pc2.printf("data=[%d]{%d][%d]/[%d]\n",j*TrAdd,i,TrValue[0],TrAdd);
00276             for(int k=0;k<TrValNum;k++)
00277                 _spi.write(TrValue[k]);
00278         }
00279         _spi.write(0x00); // DUMMY transfer
00280         _spi.write(0x00); // DUMMY transfer
00281 //        wait_ms(1);      //1.8Hz simulation
00282 //        wait_ms(2);      //1.35Hz simulation
00283         wait_us(6);
00284         _cs  = 0;
00285         if(pol) pol=0x00;
00286         else    pol=0x01;
00287 
00288 }
00289 
00290 /**
00291 * @brief  Get Edited data for SPI transfer from line buffer
00292 * @param[in] int x : horizontal allocation left to right
00293 * @param[in] uint8_t* buff : buffer data for Display
00294 */
00295 int* memLCD8::GetPixelValueFromLineBuffer(int _x,uint8_t* buff)
00296 {
00297     //bitmap data = 4bit data => modify transfer data bit size;
00298     switch(TrModeCommand)
00299     {
00300     case 0x90: //TrBIT4:
00301         // buffer 2pixel/1byte => 2pixel/1byte  buffe 2byte毎進める。
00302         TrValue[0] = _dispLINEBUF[_x];
00303         break;
00304     case 0x80://TrBIT3:
00305         // buffer 2pixel/1byte => 3pixel-1subpixel/1bye (24 pixel/3byte) buffer 3byte毎進める。
00306         for(int j=0;j<3;j++) TrValue[j] = 0;
00307         //for( int i = 0 ; i<12 ; i--)
00308         {
00309             //4 bit RGBN(Nは予備) => 3bit RGB
00310             if( _width/2 > _x )
00311             {
00312                 TrValue[0] = TrValue[0] | ( ( (_dispLINEBUF[_x    ]&0xE0) ) );
00313                 TrValue[0] = TrValue[0] | ( ( (_dispLINEBUF[_x    ]&0x0E) ) << 1);
00314             }
00315             if( _width/2 > _x + 1 )
00316             {
00317                 TrValue[0] = TrValue[0] | ( ( (_dispLINEBUF[_x + 1]&0xC0) ) >> 6);
00318 
00319                 TrValue[1] = TrValue[1] | ( ( (_dispLINEBUF[_x + 1]&0x20) ) << 2);
00320                 TrValue[1] = TrValue[1] | ( ( (_dispLINEBUF[_x + 1]&0x0E) ) << 3);
00321             }
00322             if( _width/2 > _x + 2 )
00323             {
00324                 TrValue[1] = TrValue[1] | ( ( (_dispLINEBUF[ _x + 2]&0xE0) ) >> 4);
00325                 TrValue[1] = TrValue[1] | ( ( (_dispLINEBUF[ _x + 2]&0x08) ) >> 3);
00326 
00327                 TrValue[2] = TrValue[2] | ( ( (_dispLINEBUF[_x + 2]&0x06) ) << 5);
00328             }
00329             if( _width/2 > _x + 3 )
00330             {
00331                 TrValue[2] = TrValue[2] | ( ( (_dispLINEBUF[ _x + 3]&0xE0) ) >> 2);
00332                 TrValue[2] = TrValue[2] | ( ( (_dispLINEBUF[_x + 3]&0x0E) ) >> 1);
00333             }    
00334         }
00335         break;
00336     case 0x88://TrBIT1:
00337         // buffer 2pixel/1byte => 8 pixel/1byte  buffe 4byte毎進める。
00338         for(int j=0;j<3;j++) TrValue[j] = 0;
00339         for(int i = 0 ; i<4 ; i++)
00340         {
00341             //Green bit => monochrome bit
00342             if( _width/2 > _x + i )
00343             {
00344                 TrValue[0] = TrValue[0] | ( ( (_dispLINEBUF[_x + i]&0x40) == 0 ? 0 : 1 ) << (7-i*2)   );
00345                 TrValue[0] = TrValue[0] | ( ( (_dispLINEBUF[_x + i]&0x04) == 0 ? 0 : 1 ) << (7-i*2)-1 );
00346                 //pc2.printf("[%d+%d][%d]<0x%x>\n",_x,i,_y,_dispBUF[_y* _width/2 + _x + i]);
00347             }
00348         }
00349         break;
00350     }
00351     return TrValue;   
00352 }
00353 
00354 /**
00355 * @brief  clear line buffer data by background color data
00356 */
00357 void memLCD8::clsLINEBUF(void)
00358 {
00359 
00360     for (int j=0; j<_width; j++) {
00361         pixel(j,_background);
00362     }
00363 }
00364 #endif
00365 //////////////////////////////////////////////////////////////////////////////
00366 // Frame buffer mode
00367 //////////////////////////////////////////////////////////////////////////////
00368 #if FRAMEBUFF_MODE
00369 
00370 /**
00371 * @brief  display the text.
00372 * @param[in] int x : horizontal allocation , up-left of text
00373 * @param[in] int y : vertical allocation , bottom-right of text
00374 * @param[in] char* text : strings
00375 */
00376 int memLCD8::textout(int x,int y,char* text)
00377 {
00378     int i=0;
00379     char_x = x;
00380     char_y = y;
00381 
00382     while(text[i] != 0x00 )
00383     {
00384        character(char_x, char_y, text[i]);
00385        i++;
00386     }
00387     return text[i];
00388 }
00389 
00390 /**
00391 * @brief  display the oblique text.
00392 * @param[in] int x : horizontal allocation , up-left of text
00393 * @param[in] int y : vertical allocation , bottom-right of text
00394 * @param[in] char* text : strings
00395 */
00396 int memLCD8::obliqueout(int x,int y,char* text)
00397 {
00398     int i=0;
00399     char_x = x;
00400     char_y = y;
00401 
00402     while(text[i] != 0x00 )
00403     {
00404        oblique(char_x, char_y, text[i]);
00405        i++;
00406     }
00407     return text[i];
00408 }
00409 
00410 /**
00411 * @brief  dispay a character by bog font. big font is that "char data" byte size is over 0xff.
00412 * @param[in] int x : horizontal allocation , up-left of text
00413 * @param[in] int y : vertical allocation , bottom-right of text
00414 * @param[in] char c : a charactor.
00415 * 
00416 */
00417 void memLCD8::character(int x, int y, int c)
00418 {
00419     unsigned int hor,vert,offset0,offset1,bpl,j,i,b; // T.Okamoto modified, for big font
00420     unsigned int headroffset;// 2018-10-26 added by Y.Saruhashi
00421     unsigned char* zeichen;
00422     unsigned char z,w;
00423 
00424     if ((c < 32) || (c > 127)) return;   // test char range
00425 
00426     //for big font
00427     offset0 = font[0];  // bytes / char uppser adress
00428     offset1 = font[1];  // bytes / char lower adress
00429     hor = font[2];      // get hor size of font
00430     vert = font[3];     // get vert size of font
00431     bpl = font[4];      // bytes per line
00432     headroffset = 5;
00433 
00434     if (char_x + hor > _width) {
00435         char_x = 0;
00436         char_y = char_y + vert;
00437         if (char_y >= _height - vert) char_y = 0; // original =  font[2]  T.Okamoto modified, for big font
00438     }
00439 
00440     zeichen = &font[(c -32) * (offset0 *256 + offset1) + headroffset]; // start of char bitmap // original =  +4  T.Okamoto modified, for big font
00441     
00442     if( _FixedFontWidth == 0 ) w = zeichen[0];                          // width of actual char
00443     else                       w = _FixedFontWidth;                     // fixed width of char
00444 
00445     for (j=0; j<vert; j++) {  //  vert line
00446         for (i=0; i<hor; i++) {   //  horz line
00447             z =  zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
00448             b = 1 << (j & 0x07);
00449             if (( z & b ) != 0x00)  pixel(x+i,y+j,_foreground);
00450             else if (_ifMarge == 0) pixel(x+i,y+j,_background);//  _background  -> _LayerBUF[index];
00451 
00452         }
00453     }
00454     if ((w + 2) < hor) char_x += w + 2;                  // x offset to next char
00455     else               char_x += hor;
00456 }
00457 
00458 /**
00459 * @brief  dispay a oblique typte character by big font. 
00460 * @param[in] int x : horizontal allocation , up-left of text
00461 * @param[in] int y : vertical allocation , bottom-right of text
00462 * @param[in] char c : a charactor.
00463 */
00464 void memLCD8::oblique(int x, int y, int c)
00465 {
00466     unsigned int hor,vert,offset0,offset1,bpl,j,i,b; // T.Okamoto modified, for big font
00467     unsigned int headroffset;// 2018-10-26 added by Y.Saruhashi
00468     unsigned char* zeichen;
00469     unsigned char z,w;
00470     if ((c < 32) || (c > 127)) return;   // test char range
00471 
00472     //for big font
00473     offset0 = font[0];  // bytes / char uppser adress
00474     offset1 = font[1];  // bytes / char lower adress
00475     hor = font[2];      // get hor size of font
00476     vert = font[3];     // get vert size of font
00477     bpl = font[4];      // bytes per line
00478     headroffset = 5;
00479 
00480     int oblique_raio=3;    // 3 = 30(%percentage) /  10
00481     int shift_x = (hor*oblique_raio)/10; //oblique pixel x size, top of char;
00482     int shift_y = vert / shift_x;        //oblique ratio for vertical.  
00483 
00484     if (char_x + hor > _width) {
00485         char_x = 0;
00486         char_y = char_y + vert;
00487         if (char_y >= _height - vert) char_y = 0;
00488     }
00489     
00490     zeichen = &font[(c -32) * (offset0 *256 + offset1) + headroffset];
00491     if( _FixedFontWidth == 0 ) w = zeichen[0];                          // actual width of char
00492     else                       w = _FixedFontWidth;                     // fixed width of char
00493 
00494     for (j=0; j<vert; j++) {  //  vert line
00495         for (i=0; i<hor; i++) {   //  horz line
00496             z =  zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
00497             b = 1 << (j & 0x07);
00498             if (( z & b ) != 0x00)  pixel(x+i+shift_x-(j/shift_y),y+j,_foreground);
00499             else if (_ifMarge == 0) pixel(x+i+shift_x-(j/shift_y),y+j,_background);//  _background  -> _LayerBUF[index];
00500 
00501         }
00502     }
00503     if ((w + 2) < hor) char_x += w + 2;                  // x offset to next char
00504     else               char_x += hor;
00505 }
00506 
00507 /**
00508 * @brief  dispay the image from symbol data
00509 */
00510 void memLCD8::Symbol(unsigned int x, unsigned int y, unsigned char *symbol)
00511 {
00512     unsigned int hor,vert,bpl,j,i,b;
00513     unsigned char* zeichen;
00514     unsigned char z,w;
00515     hor = symbol[0];                       // get hor size of font
00516     vert = symbol[1];                      // get vert size of font
00517     bpl = symbol[2];                       // bytes per line
00518 
00519     if (char_x + hor > _width) {
00520         char_x = 0;
00521         char_y = char_y + vert;
00522         if (char_y >= _height - symbol[1]) char_y = 0;
00523     }
00524 
00525     zeichen = &symbol[3];
00526     w = zeichen[0];                          // actual width of char
00527     for (j=0; j<vert; j++) {  //  vert line
00528         for (i=0; i<hor; i++) {   //  horz line
00529             z =  zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
00530             b = 1 << (j & 0x07);
00531             if (( z & b ) != 0x00)  pixel(x+i,y+j,_foreground);
00532             else if (_ifMarge == 0) pixel(x+i,y+j,_background);//  _background  -> _LayerBUF[index];
00533         }
00534     }
00535     if ((w + 2) < hor) char_x += w + 2;                  // x offset to next char
00536     else               char_x += hor;
00537 }
00538 
00539 /**
00540 * @brief  dispay a circle line by color data
00541 */
00542 void memLCD8::circle(int x0, int y0, int r, uint8_t color)
00543 {
00544     int x = -r, y = 0, err = 2-2*r, e2;
00545     do {
00546         pixel(x0-x, y0+y,color);
00547         pixel(x0+x, y0+y,color);
00548         pixel(x0+x, y0-y,color);
00549         pixel(x0-x, y0-y,color);
00550         e2 = err;
00551         if (e2 <= y) {
00552             err += ++y*2+1;
00553             if (-x == y && e2 <= x) e2 = 0;
00554         }
00555         if (e2 > x) err += ++x*2+1;
00556     } while (x <= 0);
00557 
00558 }
00559 
00560 /**
00561 * @brief  dispay a filled circle by color data
00562 */
00563 void memLCD8::fillcircle(int x0, int y0, int r, uint8_t color)
00564 {
00565     int x = -r, y = 0, err = 2-2*r, e2;
00566     do {
00567         vline(x0-x, y0-y, y0+y, color);
00568         vline(x0+x, y0-y, y0+y, color);
00569         e2 = err;
00570         if (e2 <= y) {
00571             err += ++y*2+1;
00572             if (-x == y && e2 <= x) e2 = 0;
00573         }
00574         if (e2 > x) err += ++x*2+1;
00575     } while (x <= 0);
00576 }
00577 
00578 /**
00579 * @brief  dispay a horizontal line by color data
00580 */
00581 void memLCD8::hline(int x0, int x1, int y, uint8_t color)
00582 {
00583     int w;
00584     w = x1 - x0 + 1;
00585     for (int j=0; j<w; j++) pixel(x0+j, y,color);
00586 }
00587 /**
00588 * @brief  dispay a vertical line by color data
00589 */
00590 void memLCD8::vline(int x, int y0, int y1, uint8_t color)
00591 {
00592     int h;
00593     h = y1 - y0 + 1;
00594     for (int j=0; j<h; j++) pixel(x, y0+j,color);
00595 }
00596 
00597 /**
00598 * @brief  dispay a line by color data
00599 */
00600 void memLCD8::line(int x0, int y0, int x1, int y1, uint8_t color)
00601 {
00602     int   dx = 0, dy = 0;
00603     int   dx_sym = 0, dy_sym = 0;
00604     int   dx_x2 = 0, dy_x2 = 0;
00605     int   di = 0;
00606 
00607     dx = x1-x0;
00608     dy = y1-y0;
00609 
00610     if (dx == 0) {        // vertical line
00611         if (y1 > y0) vline(x0,y0,y1,color);
00612         else vline(x0,y1,y0,color);
00613         return;
00614     }
00615 
00616     if (dx > 0) {
00617         dx_sym = 1;
00618     } else {
00619         dx_sym = -1;
00620     }
00621     if (dy == 0) {        // horizontal line
00622         if (x1 > x0) hline(x0,x1,y0,color);
00623         else  hline(x1,x0,y0,color);
00624         return;
00625     }
00626 
00627     if (dy > 0) {
00628         dy_sym = 1;
00629     } else {
00630         dy_sym = -1;
00631     }
00632 
00633     dx = dx_sym*dx;
00634     dy = dy_sym*dy;
00635 
00636     dx_x2 = dx*2;
00637     dy_x2 = dy*2;
00638 
00639     if (dx >= dy) {
00640         di = dy_x2 - dx;
00641         while (x0 != x1) {
00642 
00643             pixel(x0, y0, color);
00644             x0 += dx_sym;
00645             if (di<0) {
00646                 di += dy_x2;
00647             } else {
00648                 di += dy_x2 - dx_x2;
00649                 y0 += dy_sym;
00650             }
00651         }
00652         pixel(x0, y0, color);
00653     } else {
00654         di = dx_x2 - dy;
00655         while (y0 != y1) {
00656             pixel(x0, y0, color);
00657             y0 += dy_sym;
00658             if (di < 0) {
00659                 di += dx_x2;
00660             } else {
00661                 di += dx_x2 - dy_x2;
00662                 x0 += dx_sym;
00663             }
00664         }
00665         pixel(x0, y0, color);
00666     }
00667     return;
00668 }
00669 /**
00670 * @brief  dispay a rectangle line by color data
00671 */
00672 void memLCD8::rect(int x0, int y0, int x1, int y1, uint8_t color)
00673 {
00674 
00675     if (x1 > x0) hline(x0,x1,y0,color);
00676     else  hline(x1,x0,y0,color);
00677 
00678     if (y1 > y0) vline(x0,y0,y1,color);
00679     else vline(x0,y1,y0,color);
00680 
00681     if (x1 > x0) hline(x0,x1,y1,color);
00682     else  hline(x1,x0,y1,color);
00683 
00684     if (y1 > y0) vline(x1,y0,y1,color);
00685     else vline(x1,y1,y0,color);
00686 
00687     return;
00688 }
00689 /**
00690 * @brief  dispay a filled rectangle by color data
00691 */
00692 void memLCD8::fillrect(int x0, int y0, int x1, int y1, uint8_t color)
00693 {
00694     int h = y1 - y0 + 1;
00695     for (int i=0; i<h; i++) hline(x0, x1, y0+i, color);
00696 }
00697 /**
00698 * @brief  Transfer One Pixel Data with x,y allocation
00699 * @param[in] int x : horizontal allocation left to right
00700 * @param[in] int y : vertival allocation top to bottom
00701 * @param[in] uint8_t color : the color data for Drawing  0x0X  x is color data(RGBC) C is not used
00702 */
00703 void memLCD8::pixel(int x, int y, uint8_t color)
00704 {
00705     if(!(x % 2)) _dispBUF[y*_width/2+x/2] =  _dispBUF[y*_width/2+x/2]&0x0F  |  (color << 4)&0xF0 ;   //MASK 0000 1111
00706     else         _dispBUF[y*_width/2+x/2] =  _dispBUF[y*_width/2+x/2]&0xF0  |  (color     )&0x0F ;   //MASK 1111 0000
00707 }
00708 
00709 /**
00710 * @brief  Get Edited data for SPI transfer
00711 * @param[in] int x : horizontal allocation left to right
00712 * @param[in] int y : vertival allocation top to bottom
00713 * @param[in] uint8_t* buff : buffer data for Display
00714 */
00715 int* memLCD8::GetPixelValue(int _x, int _y ,uint8_t* buff)
00716 {
00717     //bitmap data = 4bit data => modify transfer data bit size;
00718     switch(TrModeCommand)
00719     {
00720     case 0x90: //TrBIT4:
00721         // buffer 2pixel/1byte => 2pixel/1byte  buffe 2byte毎進める。
00722         TrValue[0] = buff[_y* _width/2 + _x];
00723         break;
00724     case 0x80://TrBIT3:
00725         // buffer 2pixel/1byte => 3pixel-1subpixel/1bye (24 pixel/3byte) buffer 3byte毎進める。
00726         for(int j=0;j<3;j++) TrValue[j] = 0;
00727         //for( int i = 0 ; i<12 ; i--)
00728         {
00729             //4 bit RGBN(Nは予備) => 3bit RGB
00730             if( _width/2 > _x )
00731             {
00732                 TrValue[0] = TrValue[0] | ( ( (buff[_y* _width/2 + _x    ]&0xE0) ) );
00733                 TrValue[0] = TrValue[0] | ( ( (buff[_y* _width/2 + _x    ]&0x0E) ) << 1);
00734             }
00735             if( _width/2 > _x + 1 )
00736             {
00737                 TrValue[0] = TrValue[0] | ( ( (buff[_y* _width/2 + _x + 1]&0xC0) ) >> 6);
00738 
00739                 TrValue[1] = TrValue[1] | ( ( (buff[_y* _width/2 + _x + 1]&0x20) ) << 2);
00740                 TrValue[1] = TrValue[1] | ( ( (buff[_y* _width/2 + _x + 1]&0x0E) ) << 3);
00741             }
00742             if( _width/2 > _x + 2 )
00743             {
00744                 TrValue[1] = TrValue[1] | ( ( (buff[_y* _width/2 + _x + 2]&0xE0) ) >> 4);
00745                 TrValue[1] = TrValue[1] | ( ( (buff[_y* _width/2 + _x + 2]&0x08) ) >> 3);
00746 
00747                 TrValue[2] = TrValue[2] | ( ( (buff[_y* _width/2 + _x + 2]&0x06) ) << 5);
00748             }
00749             if( _width/2 > _x + 3 )
00750             {
00751                 TrValue[2] = TrValue[2] | ( ( (buff[_y* _width/2 + _x + 3]&0xE0) ) >> 2);
00752                 TrValue[2] = TrValue[2] | ( ( (buff[_y* _width/2 + _x + 3]&0x0E) ) >> 1);
00753             }    
00754         }
00755         break;
00756     case 0x88://TrBIT1:
00757         // buffer 2pixel/1byte => 8 pixel/1byte  buffe 4byte毎進める。
00758         for(int j=0;j<3;j++) TrValue[j] = 0;
00759         for(int i = 0 ; i<4 ; i++)
00760         {
00761             //Green bit => monochrome bit
00762             if( _width/2 > _x + i )
00763             {
00764                 TrValue[0] = TrValue[0] | ( ( (buff[_y* _width/2 + _x + i]&0x40) == 0 ? 0 : 1 ) << (7-i*2)   );
00765                 TrValue[0] = TrValue[0] | ( ( (buff[_y* _width/2 + _x + i]&0x04) == 0 ? 0 : 1 ) << (7-i*2)-1 );
00766                 //pc2.printf("[%d+%d][%d]<0x%x>\n",_x,i,_y,_dispBUF[_y* _width/2 + _x + i]);
00767             }
00768         }
00769         break;
00770     }
00771     return TrValue;   
00772 }
00773 
00774 /**
00775 * @brief  Transfer Pixel Data from buffer to Display
00776 * @param[in] int transfermode : instruction the transfer data size ,4bit,3bit,1bit
00777 */
00778 void memLCD8::writeDISP(int transfermode)    // refresh whole display
00779 {
00780     char pol = 0;
00781     //char command = 0x90; // 8b 1*0xNNNN *=POL x=AutoW  A  1010
00782     SetTransfermode(transfermode);
00783     
00784     // frame
00785     for (int i=0; i<_height; i++) {
00786         // line
00787         wait_us(6);
00788         _cs  = 1;
00789         wait_us(6);
00790         _spi.write(TrModeCommand | (pol << 6) | (i+1)>>8 ); // COMMAND
00791         //pc2.printf("com 0x%x\n",TrModeCommand | (pol << 6) | (i+1)>>8);
00792         
00793         _spi.write((i+1)& 0x00FF ); // V ADDR
00794         //pc2.printf("v adr 0x%x\n",(i+1)& 0x00FF);
00795         
00796         for(int j=0; j<_width; j+=TrAdd)
00797         {
00798             GetPixelValue(j,i,_dispBUF);
00799             //pc2.printf("data=[%d]{%d][%d]/[%d]\n",j*TrAdd,i,TrValue[0],TrAdd);
00800             for(int k=0;k<TrValNum;k++)
00801                 _spi.write(TrValue[k]);
00802         }
00803         _spi.write(0x00); // DUMMY transfer
00804         _spi.write(0x00); // DUMMY transfer
00805 //        wait_ms(1);      //1.8Hz simulation
00806 //        wait_ms(2);      //1.35Hz simulation
00807         wait_us(6);
00808         _cs  = 0;
00809         if(pol) pol=0x00;
00810         else    pol=0x01;
00811     }
00812 }
00813 
00814 /**
00815 * @brief  Transfer Pixel Data  : from Start line number to Display of frame buffer
00816 * @param[in] int startline : Start line number to Display
00817 * @param[in] int endline : end line number to Display
00818 * @param[in] int transfermode : instruction the transfer data size ,4bit,3bit,1bit
00819 */
00820 void memLCD8::writeDISP(int startline , int endline , int transfermode)    // refresh display selected line
00821 {
00822     char pol = 0;
00823     //char command = 0x90; // 8b 1*0xNNNN *=POL x=AutoW  A  1010
00824     SetTransfermode(transfermode);
00825     
00826     // frame
00827     for (int i=startline; i<=endline; i++) {
00828         if( i >= _height ) continue;
00829         if( i <0   ) continue;
00830         
00831         // line
00832         wait_us(6);
00833         _cs  = 1;
00834         wait_us(6);
00835         _spi.write(TrModeCommand | (pol << 6) | (i+1)>>8 ); // COMMAND
00836         //pc2.printf("com 0x%x\n",TrModeCommand | (pol << 6) | (i+1)>>8);
00837         
00838         _spi.write((i+1)& 0x00FF ); // V ADDR
00839         //pc2.printf("v adr 0x%x\n",(i+1)& 0x00FF);
00840         
00841         for(int j=0; j<_width; j+=TrAdd)
00842         //for(int j=0; j<100; j+=TrAdd)
00843         {
00844             GetPixelValue(j,i,_dispBUF);
00845             //pc2.printf("data=[%d]{%d][%d]/[%d]\n",j*TrAdd,i,TrValue[0],TrAdd);
00846             for(int k=0;k<TrValNum;k++)
00847                 _spi.write(TrValue[k]);
00848         }
00849         _spi.write(0x00); // DUMMY transfer
00850         _spi.write(0x00); // DUMMY transfer
00851 //        wait_ms(1);      //1.8Hz simulation
00852 //        wait_ms(2);      //1.35Hz simulation
00853         wait_us(6);
00854         _cs  = 0;
00855         if(pol) pol=0x00;
00856         else    pol=0x01;
00857     }
00858 }
00859 
00860 /**
00861 * @brief  Transfer Pixel Data from frame buffer to Display
00862 */
00863 void memLCD8::writeDISP(void)    // refresh whole display
00864 {
00865 
00866     char pol = 0;
00867     char command = 0x90; // 8b 1*0xNNNN *=POL x=AutoW  A  1010
00868 
00869     // frame
00870     for (int i=0; i<_height; i++) {
00871         // line
00872         wait_us(6);
00873         _cs  = 1;
00874         wait_us(6);
00875         _spi.write(command | (pol << 6) | (i+1)>>8 ); // COMMAND
00876         _spi.write((i+1)& 0x00FF ); // V ADDR
00877         for(int j=0; j<_width/2; j++) _spi.write(_dispBUF[i*_width/2 + j]);
00878         _spi.write(0x00); // DUMMY transfer
00879         _spi.write(0x00); // DUMMY transfer
00880         wait_us(6);
00881         _cs  = 0;
00882         if(pol) pol=0x00;
00883         else    pol=0x01;
00884     }
00885 }
00886 
00887 /**
00888 * @brief  clear buffer data by background color data
00889 */
00890 void memLCD8::clsBUF(void)
00891 {
00892 
00893     for (int i=0; i<_height; i++) {
00894         for (int j=0; j<_width; j++) {
00895             pixel(j,i,_background);
00896         }
00897     }
00898 }
00899 #if MOVIEBUFF_MODE
00900 /**
00901 * @brief  Transfer One Pixel Data with x,y allocation to Animation buffer
00902 * @param[in] int x : horizontal allocation left to right
00903 * @param[in] int y : vertival allocation top to bottom
00904 * @param[in] uint8_t color : the color data for Drawing  0x0X  x is color data(RGBC) C is not used
00905 * @param[in] int memnu : animation buffer number.
00906 */
00907 void memLCD8::movie_pixel(int x, int y, uint8_t color,int memnum)
00908 {
00909     //pc2.printf("movie_pixel[%d][%d]col[%d]\n",x,y,color);
00910     if(!(x % 2)) _dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2] =  _dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2]&0x0F  |  (color << 4)&0xF0 ;   //MASK 0000 1111
00911     else         _dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2] =  _dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2]&0xF0  |  (color     )&0x0F ;   //MASK 1111 0000
00912 }
00913 
00914 /**
00915 * @brief  Transfer Pixel Data of Animation buffer with x,y allocation to frame buffer.
00916 * @param[in] int sx : horizontal start allocation left to right
00917 * @param[in] int sy : vertival start allocation top to bottom
00918 * @param[in] int memnu : animation buffer number.
00919 */
00920 void memLCD8::makeMovieFrame(int sx , int sy, int memnum)
00921 {
00922     int x,y;
00923     //pc2.printf("1<%d,%d>\n",_width,_height);
00924     for(y = 0; y < MOVIE_VERT_SIZE;y++)
00925     {
00926         for(x = 0; x < MOVIE_HORI_SIZE ;x+=2)
00927         {
00928                 if( (sx + x) >= _width ) continue;
00929                 if( (sx + x) < 0 ) continue;
00930                 if( (sy + y) >= _height ) continue;
00931                 if( (sy + y) < 0 ) continue;
00932                 
00933                 _dispBACKUPBUF[y*MOVIE_HORI_SIZE/2+x/2] = _dispBUF[(sy+y)*(_width)/2+(sx+x)/2];
00934 
00935                 if( (_dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2]&0xF0) != 0 )
00936                     _dispBUF[(sy+y)*(_width)/2+(sx+x)/2] = _dispBUF[(sy+y)*(_width)/2+(sx+x)/2]&0x0F | _dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2]&0xF0;   //MASK 0000 1111
00937 
00938                 if( (_dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2]&0x0F) != 0 )
00939                     _dispBUF[(sy+y)*(_width)/2+(sx+x)/2] =  _dispBUF[(sy+y)*(_width)/2+(sx+x)/2]&0xF0 | _dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2]&0x0F;   //MASK 0000 1111
00940         
00941             //pc2.printf("dispMOVIEBUF[%d][%d] = %d\n",x,y,_dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2]);
00942            //_dispBUF[(sy+y)*(_width)/2+(sx+x)/2] = _dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2];
00943         }
00944     }
00945     //pc2.printf("memnum=%d,x=%d,y=%d>sx=%d,sy=%d\n",memnum,sx,sy,(sx+x)-1,(sy+y)-1);
00946 
00947 }
00948 /**
00949 * @brief  Transfer Pixel Data of Animation buffer with x,y allocation to frame buffer.  animation data read right to left.
00950 * @param[in] int sx : horizontal start allocation left to right
00951 * @param[in] int sy : vertival start allocation top to bottom
00952 * @param[in] int memnu : animation buffer number.
00953 */
00954 void memLCD8::makeMovieFrame_Reverse(int sx , int sy, int memnum)
00955 {
00956     int x,y;
00957     //pc2.printf("1<%d,%d>\n",_width,_height);
00958     for(y = 0; y < MOVIE_VERT_SIZE ;y++)
00959     {
00960         for(x = 0; x < MOVIE_HORI_SIZE  ;x+=2)
00961         {
00962                 if( (sx + x) >= _width ) continue;
00963                 if( (sx + x) < 0 ) continue;
00964                 if( (sy + y) >= _height ) continue;
00965                 if( (sy + y) < 0 ) continue;
00966                 
00967                 _dispBACKUPBUF[y*MOVIE_HORI_SIZE/2+x/2] = _dispBUF[(sy+y)*(_width)/2+(sx+x)/2];
00968 
00969                 if( (_dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+(MOVIE_HORI_SIZE-2-x)/2]&0xF0) != 0 )
00970                     _dispBUF[(sy+y)*(_width)/2+(sx+x)/2] = _dispBUF[(sy+y)*(_width)/2+(sx+x)/2]&0x0F | _dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+(MOVIE_HORI_SIZE-2-x)/2]&0xF0;   //MASK 0000 1111
00971 
00972                 if( (_dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+(MOVIE_HORI_SIZE-2-x)/2]&0x0F) != 0 )
00973                     _dispBUF[(sy+y)*(_width)/2+(sx+x)/2] = _dispBUF[(sy+y)*(_width)/2+(sx+x)/2]&0xF0 | _dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+(MOVIE_HORI_SIZE-2-x)/2]&0x0F;   //MASK 0000 1111
00974         
00975             //pc2.printf("dispMOVIEBUF[%d][%d] = %d\n",x,y,_dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2]);
00976            //_dispBUF[(sy+y)*(_width)/2+(sx+x)/2] = _dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2];
00977         }
00978     }
00979     //pc2.printf("memnum=%d,x=%d,y=%d>sx=%d,sy=%d\n",memnum,sx,sy,(sx+x)-1,(sy+y)-1);
00980 
00981 }
00982 /**
00983 * @brief  Transfer Pixel Data of Animation buffer with x,y allocation to frame buffer.  animation data bottom to top.
00984 * @param[in] int sx : horizontal start allocation left to right
00985 * @param[in] int sy : vertival start allocation top to bottom
00986 * @param[in] int memnu : animation buffer number.
00987 */
00988 void memLCD8::makeMovieFrame_Updown(int sx , int sy, int memnum)
00989 {
00990     int x,y;
00991     //pc2.printf("1<%d,%d>\n",_width,_height);
00992     for(y = 0; y < MOVIE_VERT_SIZE ;y++)
00993     {
00994         for(x = 0; x < MOVIE_HORI_SIZE  ;x+=2)
00995         {
00996                 if( (sx + x) >= _width ) continue;
00997                 if( (sx + x) < 0 ) continue;
00998                 if( (sy + y) >= _height ) continue;
00999                 if( (sy + y) < 0 ) continue;
01000                 
01001                 _dispBACKUPBUF[y*MOVIE_HORI_SIZE/2+x/2] = _dispBUF[(sy+y)*(_width)/2+(sx+x)/2];
01002 
01003                 if( (_dispMOVIEBUF[memnum][(MOVIE_VERT_SIZE-1-y)*MOVIE_HORI_SIZE/2+x/2]&0xF0) != 0 )
01004                     _dispBUF[(sy+y)*(_width)/2+(sx+x)/2] = _dispBUF[(sy+y)*(_width)/2+(sx+x)/2]&0x0F | _dispMOVIEBUF[memnum][(MOVIE_VERT_SIZE-1-y)*MOVIE_HORI_SIZE/2+x/2]&0xF0;   //MASK 0000 1111
01005 
01006                 if( (_dispMOVIEBUF[memnum][(MOVIE_VERT_SIZE-1-y)*MOVIE_HORI_SIZE/2+x/2]&0x0F) != 0 )
01007                     _dispBUF[(sy+y)*(_width)/2+(sx+x)/2] = _dispBUF[(sy+y)*(_width)/2+(sx+x)/2]&0xF0 | _dispMOVIEBUF[memnum][(MOVIE_VERT_SIZE-1-y)*MOVIE_HORI_SIZE/2+x/2]&0x0F;   //MASK 0000 1111
01008         
01009             //pc2.printf("dispMOVIEBUF[%d][%d] = %d\n",x,y,_dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2]);
01010            //_dispBUF[(sy+y)*(_width)/2+(sx+x)/2] = _dispMOVIEBUF[memnum][y*MOVIE_HORI_SIZE/2+x/2];
01011         }
01012     }
01013     //pc2.printf("memnum=%d,x=%d,y=%d>sx=%d,sy=%d\n",memnum,sx,sy,(sx+x)-1,(sy+y)-1);
01014 
01015 }
01016 /**
01017 * @brief  Transfer  Pixel Data of backuped original frame buffer with x,y allocation to frame buffer.
01018 * @param[in] int sx : horizontal start allocation left to right
01019 * @param[in] int sy : vertival start allocation top to bottom
01020 * @param[in] int memnu : animation buffer number.
01021 */
01022 void memLCD8::RestoreMovieFrame(int sx , int sy, int memnum)
01023 {
01024     int x,y;
01025     //pc2.printf("1<%d,%d>\n",_width,_height);
01026     for(y = 0; y < MOVIE_VERT_SIZE;y++)
01027     {
01028         for(x = 0; x < MOVIE_HORI_SIZE ;x++)
01029         {
01030            if( (sx + x) >= _width ) continue;
01031            if( (sx + x) < 0 ) continue;
01032            if( (sy + y) >= _height ) continue;
01033            if( (sy + y) < 0 ) continue;
01034            _dispBUF[(sy+y)*(_width)/2+(sx+x)/2]=_dispBACKUPBUF[y*MOVIE_HORI_SIZE/2+x/2];
01035         }
01036     }
01037     //pc2.printf("memnum=%d,x=%d,y=%d>sx=%d,sy=%d\n",memnum,sx,sy,(sx+x)-1,(sy+y)-1);
01038 
01039 }
01040 //end MOVIEBUFF_MODE
01041 #endif
01042 //end FRAMEBUFF_MODE
01043 #endif
01044