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
MIP8F_SPI.cpp
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
Generated on Sat Jul 16 2022 04:30:34 by 1.7.2