Version 6.0. Animaiton demo.

Dependents:   MIP8f_FRDM_Animation_sample

MIP8F_SPI_Ver6.0

Ver6.0 Addtional function is animation code sample.

Revision:
0:b2d46804658c
Child:
1:2b85e7edcc4e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MIP8F_SPI.cpp	Mon Oct 22 04:21:43 2018 +0000
@@ -0,0 +1,593 @@
+/**
+* @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;
+}
+