Animation demo with MIP8F_SPI_Ver60

Dependencies:   mbed MIP8F_SPI_Ver60 MIP8f_FRDM_LineBuffer_sample MIP8f_FRDM_TransferMode_sample

Introduction

Animation Demo. Some Goldfish swin in water, from left to right, from bottom to top. Color and monochrome version

Only for LPM027M128x (400x240) ,JDI DIsplay.

Other information , please refer to https://os.mbed.com/teams/JapanDisplayInc/code/MIP8f_FRDM_sample/

Usage

Copy Setting File and Image to micro SD-CARD. you can NOT use same sample color images of OTHER VERSION SAMPLE.

a) Download the following file corresponding to the target panel, and rename file identifier (.bin -> .zip), and unzip the file on micro SD Card's root directory.

LPM027M128x (400x240) :/media/uploads/JDI_Mbed_Team/goldfish_400x240.bin

b) Insert micro SD-CARD to FRDM-K64F. c) Upload binary file to FRDM-K64F.and push Reset Button.

Other information

refer to Usage on https://os.mbed.com/teams/JapanDisplayInc/code/MIP8f_FRDM_sample/

this Sample Code (.bin)

/media/uploads/JDI_Mbed_Team/mip8f_frdm_animation_sample.k64f.bin

main.cpp

Committer:
JDI_Mbed_Team
Date:
2018-11-22
Revision:
21:d1beeb6c4a53
Parent:
20:1129e4e1ab76

File content as of revision 21:d1beeb6c4a53:

/**
* @file main.cpp
* @brief Ver6.0 Sample source code for MIP8 diplay. 
* @details  
* Ver6.0 Addtional function is Animation sample code. goldfish swin form left to right, from bottom to top.
* Ver5.0 Addtional function is checking the refresh display speed between 4bit,3bit and 1bit transfer mode 
* Ver4.0 Addtional function is Line buffer version.the Sample bitmap display color and monochrome by line buffer.
* Ver3.0 Addtional function is font display. this demo code is the nunber is counted up like a meter panel
* ver2.0 Addtional function is Monochome display by 1bit mode of SPI transfer.
*
* spi-transfer to Display has 3 mode. 
* 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.
* 3bit mode is color display, this bit arrange is  R,G,B.   R,G,B = R,G,B subpixel bit.  No bit is Dummy.
* 1bit mode is monocrome display,high speed refresh mode. a only Green subpixel of bitmap data is transfered.
* <License>
* 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 "stdio.h"
#include "string"
#include "mbed.h"
#include "MIP8F_SPI.h"
#include "SDFileSystem.h"
#include "StateSW.h"
#include "TglSW.h"

#include "Arial12x12.h"
#include "Arial24x23.h"
#include "Arial28x28.h"
#include "Arial37x36.h"
#include "Arial42x42.h"
#include "font_big.h"
#include "Arial94x94.h"

#define ON  1
#define OFF 0

//K64F
SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); // mosi,miso,sck,cs
memLCD8 WD(PTD2,PTD3,PTD1,PTD0,PTC4,PTD3); //PTC12);  // mosi,miso,clk,cs,disp,power
PwmOut BK(PTC3);
PwmOut COM60HZ(PTC10);    //add 20161108 
DigitalOut COMSEL(PTA2,0);    //add 20161108
DigitalOut BLCTRL(PTB10,0);    //add 20171115
// SW2
StateSW swPWMorOFF(SW2); //PTC6); 
InterruptIn PWMorOFF(SW2);
// SW3
TglSW HaltSW(SW3);  //PTA4); 
DigitalIn TexSW(SW3);

//for debug
Serial pc(USBTX, USBRX); // tx, rx

void SDtex2BUF(char *filepath);

//function prototype
void SD2BUF(char *filepath);
void ifOFFseq(void);
void ifswPWM(void);
void OffSequence(void);
void DispAllDir(const char *fsrc);
void ReadBmp(const char *fsrc, uint32_t FileNum);
uint32_t CntFile(const char *fsrc);

void fish_swim_RightToLeft(int y,int Speed,int No,int transfermode);
void fish_swim_LeftToRight(int y,int Speed,int No,int transfermode);
void fish_swim_BottomToTop(int x,int Speed,int No,int transfermode);
void fish_swim_TopToBottom(int x,int Speed,int No,int transfermode);
void fish_Surprise_LeftToRight(int y,int Speed,int no,int no2,int transfermode);
//Grobal value
int  ifMargeTXT = 0;
int  width = 400;
int  height= 240;

float BKduty = 0;
float BKjudge = 0;
//double BKduty = 0;
float bk_timer = 1.0;
int   blduty = 0;
int   bloff = 0;
int   blctrl_sel = 0; //0:40mA, 1:160mA //Y.S
// Readed bitmap format, Color bit size = 1,4,8,(16),24,32
uint16_t bmp_bitcount;

void ReadMovieBmp(const char *fsrc, uint32_t FileNum);

int main() {

    uint32_t filenum;
    char filepath[60];
    uint32_t filenum2;
    char filepath2[60];
    //char countup[3+1];
    //char KMPH[4+1];
    //char Trans[13+1];
    
    sd.disk_initialize();
    HaltSW.Enable(1);


    FILE *fp = fopen("/sd/settings2.txt", "rb");    //read binary
    if(fp != NULL) {
        fscanf(fp, "%d",&width);     //width read
        fscanf(fp, "%d",&height);    //height read
        fscanf(fp, "%d",&blctrl_sel);//blct_sel read //0:40mA, 1:160mA
        //sprintf(filepath,"/sd/%dx%d",width,height); //DispAllDir("/sd/180x180")    //file name write to filepath
        sprintf(filepath,"/sd/backgrand_logo%dx%d",width,height); //DispAllDir("/sd/180x180")    //file name write to filepath
        sprintf(filepath2,"/sd/fish%dx%d",width,height); //DispAllDir("/sd/180x180")    //file name write to filepath
        fclose(fp);  
    } else {
        FILE *fp = fopen("/sd/settings.txt", "rb");    //read binary
        if(fp != NULL) {
            fscanf(fp, "%d",&width);     //width read
            fscanf(fp, "%d",&height);    //height read
            sprintf(filepath,"/sd/%dx%d",width,height); //DispAllDir("/sd/180x180")    //file name write to filepath
            fclose(fp);  
        } else{ 
            width =180;
            height=180;
            sprintf(filepath,"/sd/180x180"); //DispAllDir("/sd/180x180")
        }
    }

  	COMSEL.write(1);    //

    BLCTRL.write(blctrl_sel);    //
    
    WD.setWH(width,height);    //input -> width, height
    WD.background(Black);      //background = black
    WD.clsBUF();               //data initialize
    WD.writeDISP();            //picture write(black)
    WD.SwDisp(1);              //disp on
    
    PWMorOFF.fall(&ifswPWM);  // Backlight    //sw2 fall edge
    PWMorOFF.rise(&ifOFFseq); // OFF Sequence    //sw2 rise edge

    swPWMorOFF.Enable(8, 2, 1);  //int ModeNum, int NoiseCancel, int OpenTime    //????
    swPWMorOFF.IfCntClose(ON);
    swPWMorOFF.IfCntState(ON);

    COM60HZ.period_ms(8);    //add 20161108
    COM60HZ.write(0.5);      //add 20161108

    BK.period_ms(1);    //1ms cycle    20161012 
    BK.write(1);    //low output    20160725 <- high output

    //DIR *d;
    filenum = CntFile(filepath);    //file number read
    pc.printf("filenum=%d\n",filenum);
	   	
    filenum2 = CntFile(filepath2);    //file number read
    pc.printf("filenum2=%d\n",filenum2);
    for(int i = 0; i < filenum2; i++)
    {
		ReadMovieBmp(filepath2,i);
	}


	//int x,y;
   	while(1)
    { //BITMAPS
    
    	for(int i = 0; i < filenum;i++)
    	{
 			//pc.printf("1\n");
			while(HaltSW.State());             // VCOM invert when image is still
    	    HaltSW.Clear();
			if( i%2 == 0 )
			{
				//color anime
				ReadBmp(filepath,i);
				WD.writeDISP(TrBIT3);
				fish_swim_RightToLeft(60,10,2,TrBIT3);
				fish_swim_TopToBottom(200,15,0,TrBIT3);
				fish_swim_BottomToTop(100,10,4,TrBIT3);
				fish_Surprise_LeftToRight(80,30,2,6,TrBIT3);
				fish_swim_RightToLeft(80,10,8,TrBIT3);
			}else{
				//monochrome anime
				ReadBmp(filepath,i);
				WD.writeDISP(TrBIT1);
				fish_swim_RightToLeft(60,10,2,TrBIT1);
				fish_swim_TopToBottom(200,15,4,TrBIT1);
				fish_swim_BottomToTop(100,10,4,TrBIT1);
				fish_Surprise_LeftToRight(80,30,2,6,TrBIT1);
				fish_swim_RightToLeft(80,5,8,TrBIT1);
			}
		}
      
    }
}
/**
* @brief Fish(bmp) swim from Right to Left
*/
void fish_swim_RightToLeft(int y,int Speed,int no,int transfermode)
{
	int x;
	int i=no;
	for(x = width ; x >=-80 ; x-=Speed )
	{
		//pc.printf("2\n");
		WD.makeMovieFrame(x,y,i);
	  	//backgrand display
		WD.writeDISP(y,y+MOVIE_VERT_SIZE,transfermode);
		WD.RestoreMovieFrame(x,y,i);
		if( ++i > no+1 ) i = no; 
	}
}
/**
* @brief Fish(bmp) swim from Left to Right
*/
void fish_swim_LeftToRight(int y,int Speed,int no,int transfermode)
{
	int x;
	int i=no;
	for(x = -80 ; x <=width+80 ; x+=Speed )
	{
		//pc.printf("2\n");
		WD.makeMovieFrame_Reverse(x,y,i);
	  	//backgrand display
		WD.writeDISP(y,y+MOVIE_VERT_SIZE,transfermode);
		WD.RestoreMovieFrame(x,y,i);
		if( ++i > no+1 ) i = no; 
	}
}
/**
* @brief Fish(bmp) swim from Left to Right,but he surprise!! and return
*/
void fish_Surprise_LeftToRight(int y,int Speed,int no,int no2,int transfermode)
{
	int x;
	int i;
	i=no;
	for(x = -80 ; x <=width-120 ; x+=Speed )
	{
		//pc.printf("2\n");
		WD.makeMovieFrame_Reverse(x,y,i);
	  	//backgrand display
		WD.writeDISP(y,y+MOVIE_VERT_SIZE,transfermode);
		WD.RestoreMovieFrame(x,y,i);
		if( ++i > no+1 ) i = no; 
	}
	//surprise
	i = no2;
	for(int j = 0 ; j < 6 ; j++ )
	{
		x = width-120;
		//pc.printf("2\n");
		WD.makeMovieFrame(x,y,i);
	  	//backgrand display
		WD.writeDISP(y,y+MOVIE_VERT_SIZE,transfermode);
		WD.RestoreMovieFrame(x,y,i);
		if( ++i > no2+1 ) i = no2;
	}
	// swim reverse
	i = no;
	for(x = width-120 ; x >= -80 ; x-=Speed )
	{
		//pc.printf("2\n");
		WD.makeMovieFrame(x,y,i);
	  	//backgrand display
		WD.writeDISP(y,y+MOVIE_VERT_SIZE,transfermode);
		WD.RestoreMovieFrame(x,y,i);
		if( ++i > no+1 ) i = no; 
	}
}

/**
* @brief Fish(bmp) swim from bottom to top
*/
void fish_swim_BottomToTop(int x,int Speed,int no,int transfermode)
{
	int y;
	int i=no;
	for(y = height ; y >=-MOVIE_VERT_SIZE ; y-=Speed )
	{
		//pc.printf("2\n");
		WD.makeMovieFrame(x,y,i);
	  	//backgrand display
		WD.writeDISP(y,y+MOVIE_VERT_SIZE+Speed,transfermode);
		WD.RestoreMovieFrame(x,y,i);
		if( ++i > no+1 ) i = no; 
	}
}
/**
* @brief Fish(bmp) swim from top to bottom
*/
void fish_swim_TopToBottom(int x,int Speed,int no,int transfermode)
{
	int y;
	int i=no;
	for(y = -MOVIE_VERT_SIZE ; y < height+Speed; y+=Speed )
	{
		//pc.printf("2\n");
		WD.makeMovieFrame_Updown(x,y,i);
	  	//backgrand display
		WD.writeDISP(y-Speed,y+MOVIE_VERT_SIZE,transfermode);
		WD.RestoreMovieFrame(x,y,i);
		if( ++i > no+1 ) i = no; 
	}
}
/**
* @brief read a bitmap file in SD. 8color mode
*/
void SD2BUF(char *filepath){
    char R8[1],G8[1],B8[1] ,DUMMY[1],bc[2];
    char RGB;
    FILE *fp ;

  	pc.printf("file=%s\n",filepath);
    fp = fopen(filepath, "rb");
    if(fp != NULL) {
        //for(int i=0; i< 54 ; i++) fscanf(fp,"%c",DUMMY);  // Discard Header 54bytes
        for(int i=0; i< 28 ; i++) fscanf(fp,"%c",DUMMY);  // Discard Header 26bytes
        fscanf(fp,"%c",&(bc[0]));// color bit size 2bytes
        fscanf(fp,"%c",&(bc[1]));// color bit size 2bytes
        for(int i=0; i< 24 ; i++) fscanf(fp,"%c",DUMMY);  // Discard Header 26bytes
        bmp_bitcount = bc[0]+bc[1]*256;
		if( bmp_bitcount == 1 )
		{
	        for(int i=0; i< 8 ; i++) fscanf(fp,"%c",DUMMY);  // Pallet Data
			int x;
	        for(int y=height-1; y>=0; y--) {
    	        for(x=0; x< width; x += 8) { //1bit monochrome 
            	    fscanf(fp, "%c",G8);
            	    for(int i=0; i < 8 ; i++ ){
	            	    RGB = 0;
            	    	if( (*G8 & 0x80) != 0)  RGB = RGB|0x0e;
	                	WD.pixel(x+i,y,RGB);
            	    	*G8 = *G8 << 1;
            	    }
            	}
            	if( width%8 != 0 )
            	{
            	    fscanf(fp, "%c",G8);
            	    int i;
            	    for(i=0; i < (width%8) ; i++ ){
	            	    RGB = 0;
            	    	if( (*G8 & 0x40) != 0)  RGB = RGB|0x0e;
	                	WD.pixel(x+i,y,RGB);
            	    	*G8 = *G8 << 1;
            	    }
            	}
            	if( y!=0){  // The last data column doesn't need padding
            		int wbyte = width/8 + ( width%8 == 0 ? 0:1 );
            		for(int x=(wbyte*3)%4; (x%4 !=0); x++) fscanf(fp, "%c",DUMMY);// 4byte boundery for every column(only windows bitmap format)
            	}
        	}
		}else
		if( bmp_bitcount == 24 )
		{
	        for(int y=height-1; y>=0; y--) {
    	        for(int x=0; x< width; x++) {    //24bit color  B 8bit -> G 8bit -> R 8bit
        	        fscanf(fp, "%c",B8);
            	    fscanf(fp, "%c",G8);
                	fscanf(fp, "%c",R8);
                
                	RGB =  RGB8(*R8,*G8,*B8);    //6bit(8bit) MIP  MASK 0000 1110
                	WD.pixel(x,y,RGB);
            	}
            	if( y!=0)  // The last data column doesn't need padding
            	for(int x=(width*3)%4; (x%4 !=0); x++) fscanf(fp, "%c",DUMMY);    // 4byte boundery for every column(only windows bitmap format)
        	}
        }
    }
    fclose(fp);
}

/**
* @brief read a text file in SD.
*/
void SDtex2BUF(char *filepath){
    int x,y,font,color;
    char text[40];
    int  ifEOF;
    FILE *fp ;

    fp = fopen(filepath, "r");
    if(fp != NULL) {
        while(ifEOF != -1){
            ifEOF = fscanf(fp,"%d,%d,%d,%d,%[^,],",&x,&y,&font,&color,text);
            WD.locate(x,y);
            WD.foreground(color);
            if      (font ==1)   WD.set_font((unsigned char*) Arial12x12);
            else if (font ==2)   WD.set_font((unsigned char*) Arial24x23); 
            else if (font ==3)   WD.set_font((unsigned char*) Arial28x28);
            else                 WD.set_font((unsigned char*) Neu42x35); 

            WD.printf("%s",text);
        }
    }
    fclose(fp);
}

/*
void DispAllDir(const char *fsrc)
{
    DIR *d = opendir(fsrc);
    struct dirent *p;
    char filepath[40];
    
    while ((p = readdir(d)) != NULL)  {
        sprintf(filepath, "%s/%s",fsrc,p->d_name);
        SD2BUF(filepath);
        WD.writeDISP();
    }
    closedir(d);
}
*/

/**
* @brief read a bitmap file in SD by file number.
*/
void ReadBmp(const char *fsrc, uint32_t FileNum)
{
    DIR *d = opendir(fsrc);
    struct dirent *p;
    char filepath[60];
    
    for(uint32_t i=0; i< FileNum; i++) readdir(d);
    if ((p = readdir(d)) != NULL)  {
        sprintf(filepath, "%s/%s",fsrc,p->d_name);
        SD2BUF(filepath);
        if(ifMargeTXT){
            sprintf(filepath, "%s_txt/%s.txt",fsrc,p->d_name);
            SDtex2BUF(filepath);
        }       
    }
    closedir(d);
}

uint32_t CntFile(const char *fsrc)
{
    DIR *d = opendir(fsrc);
    uint32_t counter = 0;
    while (readdir(d)!= NULL) counter++;
    closedir(d);
    return counter;
}

void OffSequence(void){
    BK.write(0);    //add 20160712 17:00
    WD.background(Black);
    WD.clsBUF();
    WD.SwDisp(0);
    WD.writeDISP();
    WD.writeDISP();
    bloff = 1;
}

void ifswPWM(void){
    if(bloff == 0){
        if(blduty >= 10){    //0
            blduty = 0;    //10
            COMSEL.write(1);    //
        }else{
            blduty += 1;    //-=
            COMSEL.write(1);    //
        }
    }else{
        blduty = 0;
        COMSEL.write(1);    //
    }
//    BKduty =  BKduty - 0.125;
//    BKduty -= 0.125;
//    if(BKduty <= 0) BKduty = 1;
//    BK.write(BKduty);
    BK.write(blduty*0.1);     //
    if(blduty == 0){
        bk_timer = 1.0;
    }else{
        bk_timer = 0.008;    //0.016   20160712
    }
}

void ifOFFseq(void){
    if(swPWMorOFF.IfAtTime()){
        swPWMorOFF.IfCntClose(OFF);
        swPWMorOFF.IfCntState(OFF);
        OffSequence();
    }
}
/**
* @brief read a bitmap,Animation page file in SD. 
*/
void SD2MOVIEBUF(char *filepath,int memnum){
    char R8[1],G8[1],B8[1] ,DUMMY[1],bc[2];
    char RGB;
    FILE *fp ;

  	pc.printf("[%d]%s\n",memnum,filepath);
    fp = fopen(filepath, "rb");
    if(fp != NULL) {
        //for(int i=0; i< 54 ; i++) fscanf(fp,"%c",DUMMY);  // Discard Header 54bytes
        for(int i=0; i< 28 ; i++) fscanf(fp,"%c",DUMMY);  // Discard Header 26bytes
        fscanf(fp,"%c",&(bc[0]));// color bit size 2bytes
        fscanf(fp,"%c",&(bc[1]));// color bit size 2bytes
        for(int i=0; i< 24 ; i++) fscanf(fp,"%c",DUMMY);  // Discard Header 26bytes
        bmp_bitcount = bc[0]+bc[1]*256;
	  	pc.printf("bitcount=%d\n",bmp_bitcount);
		if( bmp_bitcount == 1 )
		{
	        for(int i=0; i< 8 ; i++) fscanf(fp,"%c",DUMMY);  // Pallet Data
			int x;
	        for(int y=MOVIE_VERT_SIZE-1; y>=0; y--) {
    	        for(x=0; x< MOVIE_HORI_SIZE; x += 8) { //1bit monochrome 
            	    fscanf(fp, "%c",G8);
            	    for(int i=0; i < 8 ; i++ ){
	            	    RGB = 0;
            	    	if( (*G8 & 0x80) != 0)  RGB = RGB|0x0e;
	                	WD.movie_pixel(x+i,y,RGB,memnum);
            	    	*G8 = *G8 << 1;
            	    }
            	}
            	if( MOVIE_HORI_SIZE%8 != 0 )
            	{
            	    fscanf(fp, "%c",G8);
            	    int i;
            	    for(i=0; i < (width%8) ; i++ ){
	            	    RGB = 0;
            	    	if( (*G8 & 0x40) != 0)  RGB = RGB|0x0e;
	                	WD.movie_pixel(x+i,y,RGB,memnum);
            	    	*G8 = *G8 << 1;
            	    }
            	}
            	if( y!=0){  // The last data column doesn't need padding
            		int wbyte = MOVIE_HORI_SIZE/8 + ( MOVIE_HORI_SIZE%8 == 0 ? 0:1 );
            		for(int x=(wbyte*3)%4; (x%4 !=0); x++) fscanf(fp, "%c",DUMMY);// 4byte boundery for every column(only windows bitmap format)
            	}
        	}
		}else
		if( bmp_bitcount == 24 )
		{
	        for(int y=MOVIE_VERT_SIZE-1; y>=0; y--) {
    	        for(int x=0; x< MOVIE_HORI_SIZE; x++) {    //24bit color  B 8bit -> G 8bit -> R 8bit
        	        fscanf(fp, "%c",B8);
            	    fscanf(fp, "%c",G8);
                	fscanf(fp, "%c",R8);
                
                	RGB =  RGB8(*R8,*G8,*B8);    //6bit(8bit) MIP  MASK 0000 1110
                	WD.movie_pixel(x,y,RGB,memnum);
            	}
            	if( y!=0)  // The last data column doesn't need padding
            	for(int x=(MOVIE_HORI_SIZE*3)%4; (x%4 !=0); x++) fscanf(fp, "%c",DUMMY);    // 4byte boundery for every column(only windows bitmap format)
        	}
        }
    }
    fclose(fp);
}
/**
* @brief read a bitmap,All Animation page file in SD. 
*/
void ReadMovieBmp(const char *fsrc, uint32_t FileNum)
{
    DIR *d = opendir(fsrc);
    struct dirent *p;
    char filepath[60];

	if( FileNum >= MOVIE_NUM ) return;
	
   	pc.printf("read bmp No%d\n",FileNum);
    for(uint32_t i=0; i< FileNum; i++) readdir(d);
    if ((p = readdir(d)) != NULL)  {
        sprintf(filepath, "%s/%s",fsrc,p->d_name);
       	SD2MOVIEBUF(filepath,FileNum);
       	pc.printf("read finish\n");
    }
    closedir(d);
}