Version 2.0. MIP8 Frame Buffer Libraly. Addtional function is monochrome display by 1bit transfer mode . it is high speed refresh rate.

Dependents:   MIP8f_FRDM_sample MIP8f_FRDM_MonochromeDisplay_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 Library source code file: Class for JDI MIP8 display
00004 * @details
00005 * Copyright 2018 Japan Display Inc.
00006 * Licensed under the Apache License, Version 2.0 (the "License");
00007 * you may not use this file except in compliance with the License.
00008 * You may obtain a copy of the License at
00009 *     http://www.apache.org/licenses/LICENSE-2.0
00010 * Unless required by applicable law or agreed to in writing, software
00011 * distributed under the License is distributed on an "AS IS" BASIS,
00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013 * See the License for the specific language governing permissions and
00014 * limitations under the License.
00015 */
00016 
00017 #include "mbed.h"
00018 #include "MIP8F_SPI.h"
00019 
00020 // for debug
00021 //Serial pc2(USBTX, USBRX); // tx, rx
00022 
00023 memLCD8::memLCD8(PinName mosi,PinName miso,PinName sclk,PinName cs,PinName disp,PinName power)
00024     : _spi(mosi, miso, sclk),_cs(cs),_disp(disp),_power(power)
00025 {
00026 
00027     _power= 0;
00028     _disp=  0;
00029     _cs  =  0;
00030     wait_us(100);
00031 
00032     _power= 1;
00033     _spi.format(8,0);                // 8bit mode3
00034     _spi.frequency(2000000);         // 2 Mhz SPI clock
00035     _spi.write(0x00);                // mbed dummy
00036 
00037     /*
00038         _cs  = 1;
00039         command(0x02);   // All crear mode
00040         _cs  = 0;
00041     */
00042 
00043 }
00044 
00045 /**
00046 * @brief  putc
00047 */
00048 int memLCD8::_putc(int value)
00049 {
00050     if (value == '\n') {    // new line
00051         char_x = 0;
00052         char_y = char_y + font[3];
00053         if (char_y >= _height - font[3]) {
00054             char_y = 0;
00055         }
00056     } else {
00057         character(char_x, char_y, value);
00058     }
00059     return value;
00060 }
00061 
00062 /**
00063 * @brief  getc
00064 */
00065 int memLCD8::_getc()
00066 {
00067     return -1;
00068 }
00069 
00070 /**
00071 * @brief  set font name
00072 */
00073 void memLCD8::set_font(unsigned char* f)
00074 {
00075     font = f;
00076 }
00077 
00078 /**
00079 * @brief  set allocation for font
00080 */
00081 void memLCD8::locate(int x, int y)
00082 {
00083     char_x = x;
00084     char_y = y;
00085 }
00086 /**
00087 * @brief  dispay character by font 
00088 */
00089 void memLCD8::character(int x, int y, int c)
00090 {
00091     unsigned int hor,vert,offset0,offset1,bpl,j,i,b; // T.Okamoto modified, for big font
00092     unsigned char* zeichen;
00093     unsigned char z,w;
00094 //    int index;
00095     if ((c < 31) || (c > 127)) return;   // test char range
00096 
00097     offset0 = font[0];       // bytes / char
00098     offset1 = font[1];       // bytes / char
00099     hor = font[2];                       // get hor size of font
00100     vert = font[3];                      // get vert size of font
00101     bpl = font[4];                       // bytes per line
00102 
00103     if (char_x + hor > _width) {
00104         char_x = 0;
00105         char_y = char_y + vert;
00106         if (char_y >= _height - font[3]) char_y = 0; // original =  font[2]  T.Okamoto modified, for big font
00107     }
00108     zeichen = &font[(c -32) * (offset0 *256 + offset1) + 5]; // start of char bitmap // original =  +4  T.Okamoto modified, for big font
00109     w = zeichen[0];                          // width of actual char
00110     for (j=0; j<vert; j++) {  //  vert line
00111         for (i=0; i<hor; i++) {   //  horz line
00112             z =  zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
00113             b = 1 << (j & 0x07);
00114 //            index = (y+j)*_width+(x+i);
00115             if (( z & b ) != 0x00)  pixel(x+i,y+j,_foreground);
00116             else if (_ifMarge == 0) pixel(x+i,y+j,_background);//  _background  -> _LayerBUF[index];
00117 
00118         }
00119     }
00120     if ((w + 2) < hor) char_x += w + 2;                  // x offset to next char
00121     else               char_x += hor;
00122 }
00123 
00124 /**
00125 * @brief  dispay a image from symbol data
00126 */
00127 void memLCD8::Symbol(unsigned int x, unsigned int y, unsigned char *symbol)
00128 {
00129     unsigned int hor,vert,bpl,j,i,b;
00130     unsigned char* zeichen;
00131     unsigned char z,w;
00132 
00133 //    int index;
00134     hor = symbol[0];                       // get hor size of font
00135     vert = symbol[1];                      // get vert size of font
00136     bpl = symbol[2];                       // bytes per line
00137 
00138     if (char_x + hor > _width) {
00139         char_x = 0;
00140         char_y = char_y + vert;
00141         if (char_y >= _height - symbol[1]) char_y = 0;
00142     }
00143     zeichen = &symbol[3];
00144     w = zeichen[0];                          // width of actual char
00145     for (j=0; j<vert; j++) {  //  vert line
00146         for (i=0; i<hor; i++) {   //  horz line
00147             z =  zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
00148             b = 1 << (j & 0x07);
00149 //            index = (y+j)*_width+(x+i);
00150             if (( z & b ) != 0x00)  pixel(x+i,y+j,_foreground);
00151             else if (_ifMarge == 0) pixel(x+i,y+j,_background);//  _background  -> _LayerBUF[index];
00152         }
00153     }
00154     if ((w + 2) < hor) char_x += w + 2;                  // x offset to next char
00155     else               char_x += hor;
00156 }
00157 
00158 /*
00159 void memLCD8::LayerCopy(void)
00160 {
00161     for(int i=0; i<FRAME_SIZE; i++) _LayerBUF[i] = _dispBUF[i];
00162 
00163 }
00164 */
00165 /**
00166 * @brief  dispay a circle line by color data
00167 */
00168 void memLCD8::circle(int x0, int y0, int r, uint8_t color)
00169 {
00170     int x = -r, y = 0, err = 2-2*r, e2;
00171     do {
00172         pixel(x0-x, y0+y,color);
00173         pixel(x0+x, y0+y,color);
00174         pixel(x0+x, y0-y,color);
00175         pixel(x0-x, y0-y,color);
00176         e2 = err;
00177         if (e2 <= y) {
00178             err += ++y*2+1;
00179             if (-x == y && e2 <= x) e2 = 0;
00180         }
00181         if (e2 > x) err += ++x*2+1;
00182     } while (x <= 0);
00183 
00184 }
00185 /**
00186 * @brief  dispay a filled circle by color data
00187 */
00188 void memLCD8::fillcircle(int x0, int y0, int r, uint8_t color)
00189 {
00190     int x = -r, y = 0, err = 2-2*r, e2;
00191     do {
00192         vline(x0-x, y0-y, y0+y, color);
00193         vline(x0+x, y0-y, y0+y, color);
00194         e2 = err;
00195         if (e2 <= y) {
00196             err += ++y*2+1;
00197             if (-x == y && e2 <= x) e2 = 0;
00198         }
00199         if (e2 > x) err += ++x*2+1;
00200     } while (x <= 0);
00201 }
00202 /**
00203 * @brief  dispay a horizontal line by color data
00204 */
00205 void memLCD8::hline(int x0, int x1, int y, uint8_t color)
00206 {
00207     int w;
00208     w = x1 - x0 + 1;
00209     for (int j=0; j<w; j++) pixel(x0+j, y,color);
00210 }
00211 
00212 /**
00213 * @brief  dispay a vertical line by color data
00214 */
00215 void memLCD8::vline(int x, int y0, int y1, uint8_t color)
00216 {
00217     int h;
00218     h = y1 - y0 + 1;
00219     for (int j=0; j<h; j++) pixel(x, y0+j,color);
00220 }
00221 /**
00222 * @brief  dispay a line by color data
00223 */
00224 void memLCD8::line(int x0, int y0, int x1, int y1, uint8_t color)
00225 {
00226     int   dx = 0, dy = 0;
00227     int   dx_sym = 0, dy_sym = 0;
00228     int   dx_x2 = 0, dy_x2 = 0;
00229     int   di = 0;
00230 
00231     dx = x1-x0;
00232     dy = y1-y0;
00233 
00234     if (dx == 0) {        /* vertical line */
00235         if (y1 > y0) vline(x0,y0,y1,color);
00236         else vline(x0,y1,y0,color);
00237         return;
00238     }
00239 
00240     if (dx > 0) {
00241         dx_sym = 1;
00242     } else {
00243         dx_sym = -1;
00244     }
00245     if (dy == 0) {        /* horizontal line */
00246         if (x1 > x0) hline(x0,x1,y0,color);
00247         else  hline(x1,x0,y0,color);
00248         return;
00249     }
00250 
00251     if (dy > 0) {
00252         dy_sym = 1;
00253     } else {
00254         dy_sym = -1;
00255     }
00256 
00257     dx = dx_sym*dx;
00258     dy = dy_sym*dy;
00259 
00260     dx_x2 = dx*2;
00261     dy_x2 = dy*2;
00262 
00263     if (dx >= dy) {
00264         di = dy_x2 - dx;
00265         while (x0 != x1) {
00266 
00267             pixel(x0, y0, color);
00268             x0 += dx_sym;
00269             if (di<0) {
00270                 di += dy_x2;
00271             } else {
00272                 di += dy_x2 - dx_x2;
00273                 y0 += dy_sym;
00274             }
00275         }
00276         pixel(x0, y0, color);
00277     } else {
00278         di = dx_x2 - dy;
00279         while (y0 != y1) {
00280             pixel(x0, y0, color);
00281             y0 += dy_sym;
00282             if (di < 0) {
00283                 di += dx_x2;
00284             } else {
00285                 di += dx_x2 - dy_x2;
00286                 x0 += dx_sym;
00287             }
00288         }
00289         pixel(x0, y0, color);
00290     }
00291     return;
00292 }
00293 /**
00294 * @brief  dispay a rectangle line by color data
00295 */
00296 void memLCD8::rect(int x0, int y0, int x1, int y1, uint8_t color)
00297 {
00298 
00299     if (x1 > x0) hline(x0,x1,y0,color);
00300     else  hline(x1,x0,y0,color);
00301 
00302     if (y1 > y0) vline(x0,y0,y1,color);
00303     else vline(x0,y1,y0,color);
00304 
00305     if (x1 > x0) hline(x0,x1,y1,color);
00306     else  hline(x1,x0,y1,color);
00307 
00308     if (y1 > y0) vline(x1,y0,y1,color);
00309     else vline(x1,y1,y0,color);
00310 
00311     return;
00312 }
00313 
00314 /**
00315 * @brief  dispay a filled rectangle by color data
00316 */
00317 void memLCD8::fillrect(int x0, int y0, int x1, int y1, uint8_t color)
00318 {
00319     int h = y1 - y0 + 1;
00320     for (int i=0; i<h; i++) hline(x0, x1, y0+i, color);
00321 }
00322 
00323 #ifdef LINEBUFF_MODE
00324 void memLCD8::pixel(int x, uint8_t color)
00325 {
00326     if(!(x % 2)) _dispBUF[x/2] =  _dispBUF[x/2]&0x0F  |  (color << 4)&0xF0 ;   //MASK 0000 1111
00327     else         _dispBUF[x/2] =  _dispBUF[x/2]&0xF0  |  (color     )&0x0F ;   //MASK 1111 0000
00328 }
00329 
00330 //void memLCD8::writeLine(int line)    // refresh gate line display
00331 void memLCD8::writeDISP(int line,int transfermode)    // refresh gate line display
00332 {
00333 
00334     char pol = 0;
00335     SetTransfermode(transfermode);
00336     
00337 
00338     // line
00339     wait_us(6);
00340     _cs  = 1;
00341     wait_us(6);
00342     _spi.write(TrModeCommand | (pol << 6) | (line+1)>>8 ); // COMMAND
00343     _spi.write((line+1)& 0x00FF ); // V ADDR
00344     for(int j=0; j<_width/2; j++) _spi.write(_dispBUF[j]);
00345     _spi.write(0x00); // DUMMY transfer
00346     _spi.write(0x00); // DUMMY transfer
00347 //    wait_ms(1);      //1.8Hz simulation
00348 //    wait_ms(2);      //1.35Hz simulation
00349     wait_us(6);
00350     _cs  = 0;
00351     if(pol) pol=0x00;
00352     else    pol=0x01;
00353 }
00354 #endif
00355 
00356 #ifndef LINEBUFF_MODE
00357 /**
00358 * @brief  Transfer One Pixel Data with x,y allocation
00359 * @param[in] int x : horizontal allocation left to right
00360 * @param[in] int y : vertival allocation top to bottom
00361 * @param[in] uint8_t color : the color data for Drawing  0x0X  x is color data(RGBC) C is not used
00362 */
00363 void memLCD8::pixel(int x, int y, uint8_t color)
00364 {
00365     if(!(x % 2)) _dispBUF[y*_width/2+x/2] =  _dispBUF[y*_width/2+x/2]&0x0F  |  (color << 4)&0xF0 ;   //MASK 0000 1111
00366     else         _dispBUF[y*_width/2+x/2] =  _dispBUF[y*_width/2+x/2]&0xF0  |  (color     )&0x0F ;   //MASK 1111 0000
00367 }
00368 /**
00369 * @brief  Transfer Pixel Data from buffer to Display
00370 * @param[in] int transfermode : instruction the transfer data size ,4bit,3bit,1bit
00371 */
00372 void memLCD8::writeDISP(int transfermode)    // refresh whole display
00373 {
00374     char pol = 0;
00375     //char command = 0x90; // 8b 1*0xNNNN *=POL x=AutoW  A  1010
00376     SetTransfermode(transfermode);
00377     
00378     // frame
00379     for (int i=0; i<_height; i++) {
00380         // line
00381         wait_us(6);
00382         _cs  = 1;
00383         wait_us(6);
00384         _spi.write(TrModeCommand | (pol << 6) | (i+1)>>8 ); // COMMAND
00385         //pc2.printf("com 0x%x\n",TrModeCommand | (pol << 6) | (i+1)>>8);
00386         
00387         _spi.write((i+1)& 0x00FF ); // V ADDR
00388         //pc2.printf("v adr 0x%x\n",(i+1)& 0x00FF);
00389         
00390         for(int j=0; j<_width; j+=TrAdd)
00391         {
00392             GetPixelValue(j,i,_dispBUF);
00393             //pc2.printf("data=[%d]{%d][%d]/[%d]\n",j*TrAdd,i,TrValue[0],TrAdd);
00394             for(int k=0;k<TrValNum;k++)
00395                 _spi.write(TrValue[k]);
00396         }
00397         _spi.write(0x00); // DUMMY transfer
00398         _spi.write(0x00); // DUMMY transfer
00399 //        wait_ms(1);      //1.8Hz simulation
00400 //        wait_ms(2);      //1.35Hz simulation
00401         wait_us(6);
00402         _cs  = 0;
00403         if(pol) pol=0x00;
00404         else    pol=0x01;
00405     }
00406 }
00407 //old function
00408 void memLCD8::writeDISP(void)    // refresh whole display
00409 {
00410 
00411     char pol = 0;
00412     char command = 0x90; // 8b 1*0xNNNN *=POL x=AutoW  A  1010
00413 
00414     // frame
00415     for (int i=0; i<_height; i++) {
00416         // line
00417         wait_us(6);
00418         _cs  = 1;
00419         wait_us(6);
00420         _spi.write(command | (pol << 6) | (i+1)>>8 ); // COMMAND
00421         _spi.write((i+1)& 0x00FF ); // V ADDR
00422         for(int j=0; j<_width/2; j++) _spi.write(_dispBUF[i*_width/2 + j]);
00423         _spi.write(0x00); // DUMMY transfer
00424         _spi.write(0x00); // DUMMY transfer
00425 //        wait_ms(1);      //1.8Hz simulation
00426 //        wait_ms(2);      //1.35Hz simulation
00427         wait_us(6);
00428         _cs  = 0;
00429         if(pol) pol=0x00;
00430         else    pol=0x01;
00431     }
00432 }
00433 #endif
00434 /**
00435 * @brief  Get Edited data for SPI transfer
00436 * @param[in] int x:horizontal allocation left to right
00437 * @param[in] int y:vertival allocation top to bottom
00438 * @param[in] uint8_t* buff:buffer data for Display
00439 */
00440 int* memLCD8::GetPixelValue(int _x, int _y ,uint8_t* buff)
00441 {
00442     //bitmap data = 4bit data => modify transfer data bit size;
00443     switch(TrModeCommand)
00444     {
00445     case 0x90: //TrBIT4:
00446         // buffer 2pixel/1byte => 2pixel/1byte  buffe 2byte毎進める。
00447         // 176/4=44  400/4 = 100  640/4=160
00448         TrValue[0] = _dispBUF[_y* _width/2 + _x];
00449         break;
00450     case 0x80://TrBIT3:
00451         // buffer 2pixel/1byte => 3pixel-1subpixel/1bye (24 pixel/3byte) buffer 3byte毎進める。
00452         // 176/3=58.666...  400/3 = 133.333...  640/3=213.333...
00453         for(int j=0;j<3;j++) TrValue[j] = 0;
00454         //for( int i = 0 ; i<12 ; i--)
00455         {
00456             //4 bit RGBN(Nは予備) => 3bit RGB
00457             if( _width/2 > _x )
00458             {
00459                 TrValue[0] = TrValue[0] | ( ( (_dispBUF[_y* _width/2 + _x    ]&0xE0) ) );
00460                 TrValue[0] = TrValue[0] | ( ( (_dispBUF[_y* _width/2 + _x    ]&0x0E) ) << 1);
00461             }
00462             if( _width/2 > _x + 1 )
00463             {
00464                 TrValue[0] = TrValue[0] | ( ( (_dispBUF[_y* _width/2 + _x + 1]&0xC0) ) >> 6);
00465 
00466                 TrValue[1] = TrValue[1] | ( ( (_dispBUF[_y* _width/2 + _x + 1]&0x20) ) << 2);
00467                 TrValue[1] = TrValue[1] | ( ( (_dispBUF[_y* _width/2 + _x + 1]&0x0E) ) << 3);
00468             }
00469             if( _width/2 > _x + 2 )
00470             {
00471                 TrValue[1] = TrValue[1] | ( ( (_dispBUF[_y* _width/2 + _x + 2]&0xE0) ) >> 4);
00472                 TrValue[1] = TrValue[1] | ( ( (_dispBUF[_y* _width/2 + _x + 2]&0x08) ) >> 3);
00473 
00474                 TrValue[2] = TrValue[2] | ( ( (_dispBUF[_y* _width/2 + _x + 2]&0x06) ) << 5);
00475             }
00476             if( _width/2 > _x + 3 )
00477             {
00478                 TrValue[2] = TrValue[2] | ( ( (_dispBUF[_y* _width/2 + _x + 3]&0xE0) ) >> 2);
00479                 TrValue[2] = TrValue[2] | ( ( (_dispBUF[_y* _width/2 + _x + 3]&0x0E) ) >> 1);
00480             }    
00481         }
00482         break;
00483     case 0x88://TrBIT1:
00484         // buffer 2pixel/1byte => 8 pixel/1byte  buffe 4byte毎進める。
00485         // 176/4=44  400/4 = 100  640/4=160
00486         for(int j=0;j<3;j++) TrValue[j] = 0;
00487         for(int i = 0 ; i<4 ; i++)
00488         {
00489             //Green bit => monochrome bit
00490             if( _width/2 > _x + i )
00491             {
00492                 TrValue[0] = TrValue[0] | ( ( (_dispBUF[_y* _width/2 + _x + i]&0x40) == 0 ? 0 : 1 ) << (7-i*2)   );
00493                 TrValue[0] = TrValue[0] | ( ( (_dispBUF[_y* _width/2 + _x + i]&0x04) == 0 ? 0 : 1 ) << (7-i*2)-1 );
00494                 //pc2.printf("[%d+%d][%d]<0x%x>\n",_x,i,_y,_dispBUF[_y* _width/2 + _x + i]);
00495             }
00496         }
00497         break;
00498     }
00499     return TrValue;   
00500 }
00501 /**
00502 * @brief  set Configuration for transfer mode
00503 * @param[in] int transfermode : instruction the transfer data size ,4bit,3bit,1bit and some parameter
00504 */
00505 void memLCD8::SetTransfermode(int transfermode)
00506 {
00507     switch(transfermode)
00508     {
00509     case TrBIT4:
00510         TrModeCommand = 0x90;
00511         TrAdd = 1;
00512         TrValNum = 1;
00513         break;
00514     case TrBIT3:
00515         TrModeCommand = 0x80;
00516         // 176/3=58.666...  400/3 = 133.333...  640/3=213.333...
00517         TrAdd = 4;
00518         TrValNum = 3;
00519         break;
00520     case TrBIT1:
00521         TrModeCommand = 0x88;
00522         // 176/4=44  400/4 = 100  640/4=160
00523         TrAdd = 4;
00524         TrValNum = 1;
00525         //pc2.printf("TrBIT1 TW%d  Tvn%d \n",TrAdd,TrValNum);
00526         break;
00527     }
00528 }
00529 /**
00530 * @brief  clear buffer data by background color data
00531 */
00532 void memLCD8::clsBUF(void)
00533 {
00534 
00535     for (int i=0; i<_height; i++) {
00536         for (int j=0; j<_width; j++) {
00537             pixel(j,i,_background);
00538         }
00539     }
00540 }
00541 
00542 /**
00543 * @brief  set color data of foreground
00544 */
00545 void memLCD8::foreground(uint8_t colour)
00546 {
00547     _foreground = colour;
00548 }
00549 
00550 /**
00551 * @brief  set color data of background
00552 */
00553 void memLCD8::background(uint8_t colour)
00554 {
00555     _background = colour;
00556 }
00557 /*
00558 void memLCD8::setmarge(bool ifMarge)
00559 {
00560     _ifMarge = ifMarge;
00561 }
00562 */
00563 
00564 /**
00565 * @brief  set a display size ,width ,height
00566 */
00567 void memLCD8::setWH(int width, int height)
00568 {
00569     _width  = width;
00570     _height = height;
00571 }
00572 
00573 /**
00574 * @brief  transfer a command code to the display by SPI
00575 */
00576 void memLCD8::command(char command)
00577 {
00578     wait_us(6);
00579     _cs  = 1;
00580     wait_us(6);
00581     _spi.write(command);//
00582     _spi.write(0x00);// dummy
00583     wait_us(6);
00584     _cs  = 0;
00585 }
00586 /**
00587 * @brief  set the Diaplay On/Off data
00588 */
00589 void memLCD8::SwDisp(bool ONorOFF)
00590 {
00591     _disp= ONorOFF;
00592 }
00593