Version 6.0. Animaiton demo.
Dependents: MIP8f_FRDM_Animation_sample
MIP8F_SPI_Ver6.0
Ver6.0 Addtional function is animation code sample.
MIP8F_SPI.cpp
- Committer:
- JDI_Mbed_Team
- Date:
- 2018-10-22
- Revision:
- 0:b2d46804658c
- Child:
- 1:2b85e7edcc4e
File content as of revision 0:b2d46804658c:
/** * @file MIP8F_SPI.cpp * @brief Library source code file: Class for JDI MIP8 display * @details * Copyright 2018 Japan Display Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mbed.h" #include "MIP8F_SPI.h" // for debug //Serial pc2(USBTX, USBRX); // tx, rx memLCD8::memLCD8(PinName mosi,PinName miso,PinName sclk,PinName cs,PinName disp,PinName power) : _spi(mosi, miso, sclk),_cs(cs),_disp(disp),_power(power) { _power= 0; _disp= 0; _cs = 0; wait_us(100); _power= 1; _spi.format(8,0); // 8bit mode3 _spi.frequency(2000000); // 2 Mhz SPI clock _spi.write(0x00); // mbed dummy /* _cs = 1; command(0x02); // All crear mode _cs = 0; */ } /** * @brief putc */ int memLCD8::_putc(int value) { if (value == '\n') { // new line char_x = 0; char_y = char_y + font[3]; if (char_y >= _height - font[3]) { char_y = 0; } } else { character(char_x, char_y, value); } return value; } /** * @brief getc */ int memLCD8::_getc() { return -1; } /** * @brief set font name */ void memLCD8::set_font(unsigned char* f) { font = f; } /** * @brief set allocation for font */ void memLCD8::locate(int x, int y) { char_x = x; char_y = y; } /** * @brief dispay character by font */ void memLCD8::character(int x, int y, int c) { unsigned int hor,vert,offset0,offset1,bpl,j,i,b; // T.Okamoto modified, for big font unsigned char* zeichen; unsigned char z,w; // int index; if ((c < 31) || (c > 127)) return; // test char range offset0 = font[0]; // bytes / char offset1 = font[1]; // bytes / char hor = font[2]; // get hor size of font vert = font[3]; // get vert size of font bpl = font[4]; // bytes per line if (char_x + hor > _width) { char_x = 0; char_y = char_y + vert; if (char_y >= _height - font[3]) char_y = 0; // original = font[2] T.Okamoto modified, for big font } zeichen = &font[(c -32) * (offset0 *256 + offset1) + 5]; // start of char bitmap // original = +4 T.Okamoto modified, for big font 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); // index = (y+j)*_width+(x+i); if (( z & b ) != 0x00) pixel(x+i,y+j,_foreground); else if (_ifMarge == 0) pixel(x+i,y+j,_background);// _background -> _LayerBUF[index]; } } if ((w + 2) < hor) char_x += w + 2; // x offset to next char else char_x += hor; } /** * @brief dispay a image from symbol data */ void memLCD8::Symbol(unsigned int x, unsigned int y, unsigned char *symbol) { unsigned int hor,vert,bpl,j,i,b; unsigned char* zeichen; unsigned char z,w; // int index; 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 - symbol[1]) char_y = 0; } zeichen = &symbol[3]; 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); // index = (y+j)*_width+(x+i); if (( z & b ) != 0x00) pixel(x+i,y+j,_foreground); else if (_ifMarge == 0) pixel(x+i,y+j,_background);// _background -> _LayerBUF[index]; } } if ((w + 2) < hor) char_x += w + 2; // x offset to next char else char_x += hor; } /* void memLCD8::LayerCopy(void) { for(int i=0; i<FRAME_SIZE; i++) _LayerBUF[i] = _dispBUF[i]; } */ /** * @brief dispay a circle line by color data */ void memLCD8::circle(int x0, int y0, int r, uint8_t color) { int x = -r, y = 0, err = 2-2*r, e2; 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); } /** * @brief dispay a filled circle by color data */ void memLCD8::fillcircle(int x0, int y0, int r, uint8_t color) { int x = -r, y = 0, err = 2-2*r, e2; 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); } /** * @brief dispay a horizontal line by color data */ void memLCD8::hline(int x0, int x1, int y, uint8_t color) { int w; w = x1 - x0 + 1; for (int j=0; j<w; j++) pixel(x0+j, y,color); } /** * @brief dispay a vertical line by color data */ void memLCD8::vline(int x, int y0, int y1, uint8_t color) { int h; h = y1 - y0 + 1; for (int j=0; j<h; j++) pixel(x, y0+j,color); } /** * @brief dispay a line by color data */ void memLCD8::line(int x0, int y0, int x1, int y1, uint8_t color) { int dx = 0, dy = 0; int dx_sym = 0, dy_sym = 0; int dx_x2 = 0, dy_x2 = 0; int di = 0; dx = x1-x0; dy = y1-y0; if (dx == 0) { /* vertical line */ if (y1 > y0) vline(x0,y0,y1,color); else vline(x0,y1,y0,color); return; } if (dx > 0) { dx_sym = 1; } else { dx_sym = -1; } if (dy == 0) { /* horizontal line */ if (x1 > x0) hline(x0,x1,y0,color); else hline(x1,x0,y0,color); return; } 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; } /** * @brief dispay a rectangle line by color data */ void memLCD8::rect(int x0, int y0, int x1, int y1, uint8_t color) { if (x1 > x0) hline(x0,x1,y0,color); else hline(x1,x0,y0,color); if (y1 > y0) vline(x0,y0,y1,color); else vline(x0,y1,y0,color); if (x1 > x0) hline(x0,x1,y1,color); else hline(x1,x0,y1,color); if (y1 > y0) vline(x1,y0,y1,color); else vline(x1,y1,y0,color); return; } /** * @brief dispay a filled rectangle by color data */ void memLCD8::fillrect(int x0, int y0, int x1, int y1, uint8_t color) { int h = y1 - y0 + 1; for (int i=0; i<h; i++) hline(x0, x1, y0+i, color); } #ifdef LINEBUFF_MODE void memLCD8::pixel(int x, uint8_t color) { if(!(x % 2)) _dispBUF[x/2] = _dispBUF[x/2]&0x0F | (color << 4)&0xF0 ; //MASK 0000 1111 else _dispBUF[x/2] = _dispBUF[x/2]&0xF0 | (color )&0x0F ; //MASK 1111 0000 } //void memLCD8::writeLine(int line) // refresh gate line display void memLCD8::writeDISP(int line,int transfermode) // refresh gate line display { char pol = 0; SetTransfermode(transfermode); // line wait_us(6); _cs = 1; wait_us(6); _spi.write(TrModeCommand | (pol << 6) | (line+1)>>8 ); // COMMAND _spi.write((line+1)& 0x00FF ); // V ADDR for(int j=0; j<_width/2; j++) _spi.write(_dispBUF[j]); _spi.write(0x00); // DUMMY transfer _spi.write(0x00); // DUMMY transfer // wait_ms(1); //1.8Hz simulation // wait_ms(2); //1.35Hz simulation wait_us(6); _cs = 0; if(pol) pol=0x00; else pol=0x01; } #endif #ifndef LINEBUFF_MODE /** * @brief Transfer One Pixel Data with x,y allocation * @param[in] int x : horizontal allocation left to right * @param[in] int y : vertival allocation top to bottom * @param[in] uint8_t color : the color data for Drawing 0x0X x is color data(RGBC) C is not used */ void memLCD8::pixel(int x, int y, uint8_t color) { if(!(x % 2)) _dispBUF[y*_width/2+x/2] = _dispBUF[y*_width/2+x/2]&0x0F | (color << 4)&0xF0 ; //MASK 0000 1111 else _dispBUF[y*_width/2+x/2] = _dispBUF[y*_width/2+x/2]&0xF0 | (color )&0x0F ; //MASK 1111 0000 } /** * @brief Transfer Pixel Data from buffer to Display * @param[in] int transfermode : instruction the transfer data size ,4bit,3bit,1bit */ void memLCD8::writeDISP(int transfermode) // refresh whole display { char pol = 0; //char command = 0x90; // 8b 1*0xNNNN *=POL x=AutoW A 1010 SetTransfermode(transfermode); // frame for (int i=0; i<_height; i++) { // line wait_us(6); _cs = 1; wait_us(6); _spi.write(TrModeCommand | (pol << 6) | (i+1)>>8 ); // COMMAND //pc2.printf("com 0x%x\n",TrModeCommand | (pol << 6) | (i+1)>>8); _spi.write((i+1)& 0x00FF ); // V ADDR //pc2.printf("v adr 0x%x\n",(i+1)& 0x00FF); for(int j=0; j<_width; j+=TrAdd) { GetPixelValue(j,i,_dispBUF); //pc2.printf("data=[%d]{%d][%d]/[%d]\n",j*TrAdd,i,TrValue[0],TrAdd); for(int k=0;k<TrValNum;k++) _spi.write(TrValue[k]); } _spi.write(0x00); // DUMMY transfer _spi.write(0x00); // DUMMY transfer // wait_ms(1); //1.8Hz simulation // wait_ms(2); //1.35Hz simulation wait_us(6); _cs = 0; if(pol) pol=0x00; else pol=0x01; } } //old function void memLCD8::writeDISP(void) // refresh whole display { char pol = 0; char command = 0x90; // 8b 1*0xNNNN *=POL x=AutoW A 1010 // frame for (int i=0; i<_height; i++) { // line wait_us(6); _cs = 1; wait_us(6); _spi.write(command | (pol << 6) | (i+1)>>8 ); // COMMAND _spi.write((i+1)& 0x00FF ); // V ADDR for(int j=0; j<_width/2; j++) _spi.write(_dispBUF[i*_width/2 + j]); _spi.write(0x00); // DUMMY transfer _spi.write(0x00); // DUMMY transfer // wait_ms(1); //1.8Hz simulation // wait_ms(2); //1.35Hz simulation wait_us(6); _cs = 0; if(pol) pol=0x00; else pol=0x01; } } #endif /** * @brief Get Edited data for SPI transfer * @param[in] int x:horizontal allocation left to right * @param[in] int y:vertival allocation top to bottom * @param[in] uint8_t* buff:buffer data for Display */ int* memLCD8::GetPixelValue(int _x, int _y ,uint8_t* buff) { //bitmap data = 4bit data => modify transfer data bit size; switch(TrModeCommand) { case 0x90: //TrBIT4: // buffer 2pixel/1byte => 2pixel/1byte buffe 2byte毎進める。 // 176/4=44 400/4 = 100 640/4=160 TrValue[0] = _dispBUF[_y* _width/2 + _x]; break; case 0x80://TrBIT3: // buffer 2pixel/1byte => 3pixel-1subpixel/1bye (24 pixel/3byte) buffer 3byte毎進める。 // 176/3=58.666... 400/3 = 133.333... 640/3=213.333... for(int j=0;j<3;j++) TrValue[j] = 0; //for( int i = 0 ; i<12 ; i--) { //4 bit RGBN(Nは予備) => 3bit RGB if( _width/2 > _x ) { TrValue[0] = TrValue[0] | ( ( (_dispBUF[_y* _width/2 + _x ]&0xE0) ) ); TrValue[0] = TrValue[0] | ( ( (_dispBUF[_y* _width/2 + _x ]&0x0E) ) << 1); } if( _width/2 > _x + 1 ) { TrValue[0] = TrValue[0] | ( ( (_dispBUF[_y* _width/2 + _x + 1]&0xC0) ) >> 6); TrValue[1] = TrValue[1] | ( ( (_dispBUF[_y* _width/2 + _x + 1]&0x20) ) << 2); TrValue[1] = TrValue[1] | ( ( (_dispBUF[_y* _width/2 + _x + 1]&0x0E) ) << 3); } if( _width/2 > _x + 2 ) { TrValue[1] = TrValue[1] | ( ( (_dispBUF[_y* _width/2 + _x + 2]&0xE0) ) >> 4); TrValue[1] = TrValue[1] | ( ( (_dispBUF[_y* _width/2 + _x + 2]&0x08) ) >> 3); TrValue[2] = TrValue[2] | ( ( (_dispBUF[_y* _width/2 + _x + 2]&0x06) ) << 5); } if( _width/2 > _x + 3 ) { TrValue[2] = TrValue[2] | ( ( (_dispBUF[_y* _width/2 + _x + 3]&0xE0) ) >> 2); TrValue[2] = TrValue[2] | ( ( (_dispBUF[_y* _width/2 + _x + 3]&0x0E) ) >> 1); } } break; case 0x88://TrBIT1: // buffer 2pixel/1byte => 8 pixel/1byte buffe 4byte毎進める。 // 176/4=44 400/4 = 100 640/4=160 for(int j=0;j<3;j++) TrValue[j] = 0; for(int i = 0 ; i<4 ; i++) { //Green bit => monochrome bit if( _width/2 > _x + i ) { TrValue[0] = TrValue[0] | ( ( (_dispBUF[_y* _width/2 + _x + i]&0x40) == 0 ? 0 : 1 ) << (7-i*2) ); TrValue[0] = TrValue[0] | ( ( (_dispBUF[_y* _width/2 + _x + i]&0x04) == 0 ? 0 : 1 ) << (7-i*2)-1 ); //pc2.printf("[%d+%d][%d]<0x%x>\n",_x,i,_y,_dispBUF[_y* _width/2 + _x + i]); } } break; } return TrValue; } /** * @brief set Configuration for transfer mode * @param[in] int transfermode : instruction the transfer data size ,4bit,3bit,1bit and some parameter */ void memLCD8::SetTransfermode(int transfermode) { switch(transfermode) { case TrBIT4: TrModeCommand = 0x90; TrAdd = 1; TrValNum = 1; break; case TrBIT3: TrModeCommand = 0x80; // 176/3=58.666... 400/3 = 133.333... 640/3=213.333... TrAdd = 4; TrValNum = 3; break; case TrBIT1: TrModeCommand = 0x88; // 176/4=44 400/4 = 100 640/4=160 TrAdd = 4; TrValNum = 1; //pc2.printf("TrBIT1 TW%d Tvn%d \n",TrAdd,TrValNum); break; } } /** * @brief clear buffer data by background color data */ void memLCD8::clsBUF(void) { for (int i=0; i<_height; i++) { for (int j=0; j<_width; j++) { pixel(j,i,_background); } } } /** * @brief set color data of foreground */ void memLCD8::foreground(uint8_t colour) { _foreground = colour; } /** * @brief set color data of background */ void memLCD8::background(uint8_t colour) { _background = colour; } /* void memLCD8::setmarge(bool ifMarge) { _ifMarge = ifMarge; } */ /** * @brief set a display size ,width ,height */ void memLCD8::setWH(int width, int height) { _width = width; _height = height; } /** * @brief transfer a command code to the display by SPI */ void memLCD8::command(char command) { wait_us(6); _cs = 1; wait_us(6); _spi.write(command);// _spi.write(0x00);// dummy wait_us(6); _cs = 0; } /** * @brief set the Diaplay On/Off data */ void memLCD8::SwDisp(bool ONorOFF) { _disp= ONorOFF; }