LCD TFT for ssd0139 driver 8 bit mode - using portout for max speed
Dependents: TFT_CJS_ssd01399_portver_prettyfont TFT_CJS_ssd01399_portver_prettyfont snake_main_game ServerLatest
Fork of LCDTFT_ssd01399 by
LCDTFT.cpp
- Committer:
- cstevens
- Date:
- 2014-09-02
- Revision:
- 2:ebedda77b33b
- Parent:
- 1:1085b6177f6e
- Child:
- 3:f999653c1069
File content as of revision 2:ebedda77b33b:
/* @file LCDTFT.cpp @version: 1.0 @web www.micros-designs.com.ar @date 30/01/11 *- Version Log --------------------------------------------------------------* * Fecha Autor Comentarios * *----------------------------------------------------------------------------* * 30/01/11 Suky Original * *----------------------------------------------------------------------------*/ /////////////////////////////////////////////////////////////////////////// //// //// //// //// //// (C) Copyright 2011 www.micros-designs.com.ar //// //// Este c�digo puede ser usado, modificado y distribuido libremente //// //// sin eliminar esta cabecera y sin garant�a de ning�n tipo. //// //// //// //// //// /////////////////////////////////////////////////////////////////////////// #include "LCDTFT.h" LCDTFT::LCDTFT(PinName PIN_RD,PinName PIN_WR,PinName PIN_RS,PinName PIN_CS,PinName PIN_RESET, BusOut *BUSLCD) : LCD_PIN_RD(PIN_RD),LCD_PIN_WR(PIN_WR),LCD_PIN_RS(PIN_RS),LCD_PIN_CS(PIN_CS),LCD_PIN_RESET(PIN_RESET){ LCD_PORT=BUSLCD; X=0; Y=0; X_min=0; X_max=LCD_X_MAX; _Alto=1; _Color=0x0000; } // global variable for screen orientation set by init bool orient=0; static const unsigned short regValues[] = { 0x0000, 0x0001, // start oscillation 0x00FF, 0x0010, // wait 16 ms 0x0007, 0x0000, //display control - zeros everything ??? 0x0013, 0x0000, // power control 3 setting = all zero 0x0011, 0x2604, //power control 2 seting = gvd voltage 0x26 vci1 voltage 0x04 0x0014, 0x0015, // power contrlol 4 setting vcmr=0 vcomh=0 vml=13 = amplitude of vcom voltage 0x0010, 0x3C00, // power control 1 bt3=0 sap=7 (0b111) bt=4 (0b100) 0x0013, 0x0040, //power control 3 PON=1 PON1=0 AON=0 0x00FF,0x0010, // wait 16ms 0x0013, 0x0060, // power control 3 PON=1 PON1=1 AON=0 0x00FF, 0x0032, // wait 50ms 0x0013, 0x0070, //power control 3 PON=1 PON1=1 AON=1 0x00FF, 0x0028, // wait 40ms 0x0001, 0x0127, // driver ouptut control 0x0002, 0x0700, //LCD driving waveform settings 0x0003, 0x1030, // entry mode settingtri=0 dfm=0 bgr=1 id1:id0=11 0x0007, 0x0000, // display control 1 pt1-0=0 vle2-1=0 spt=0 gon=0 rev=0 d1-0=0 0x0008, 0x0404, //black period control fp3-0=4 bp3-0=4 0x000B, 0x0200, //frame cycle setting nd1-0=0 sdt1-0=2 ecs2-0=0 div1-0=0 dcr_ex=0 dcr2-0=0 rtn1-0=0 0x000C, 0x0000, //external interface controlrm=0 dm1-0=0 rim1-0=0 0x00015,0x0000, //sub panel control sub_im1-0=0 stn_en=0 mpu_mode=0 fcv_en=0 //gamma setting 0x0030, 0x0000, 0x0031, 0x0606, 0x0032, 0x0006, 0x0033, 0x0403, 0x0034, 0x0107, 0x0035, 0x0101, 0x0036, 0x0707, 0x0037, 0x0304, 0x0038, 0x0A00, 0x0039, 0x0706, // end of gamma settings 0x0040, 0x0000, // gate scan position (start g1 scan) scn5-0=0 0x0041, 0x0000, // vertical scroll setting vl8-0=0 0x0042, 0x013F, // screen end position se18-10=0x13F 0x0043, 0x0000, // screen_start position ss28-20=0 0x0044, 0x0000, // 2nd screen driving position end 00 0x0045, 0x0000, //2nd screen driving position start =00 0x0046, 0xEF00, //window addre horizontal ram for x0,x1 HEA=0xEF HSA=00 ie x=0 and x=239 0x0047, 0x013F, //vertical ram address end vea=0x13F ie y=319 0x0048, 0x0000, //vertical ram address start=00 ie y=0 0x0007, 0x0011, //dispaly control 1 0x00FF, 0x0028, //wait 40ms 0x0007, 0x0017, //display control 1 }; void LCDTFT::vLCDTFTSetParametersPrintf(unsigned short Xo,unsigned short Yo,unsigned short Xmin,unsigned short Xmax,unsigned char Alto, unsigned short Color,unsigned short BackColor){ X=Xo; Y=Yo; X_min=Xmin; X_max=Xmax; _Alto=Alto; _Color=Color; _Background=BackColor; } int LCDTFT::_putc(int value){ char Fmt[2]={value,0}; if(value=='\n'){ X=X_min; Y+=8*_Alto + 1; }else{ vLCDTFTText(X,Y,(const char *)&Fmt[0],&ARIAL[0],_Alto,_Color,_Background); X+=5*_Alto+1; if(X >= X_max){ X = X_min; Y += 8*_Alto + 1; } } return(value); } int LCDTFT::_getc(){ return(-1); } void LCDTFT::vLCDTFTWriteCommand(unsigned short Data){ LCD_PIN_RS=0; LCD_PIN_CS=0; LCD_PORT->write(Data>>8); // MSB so with an 8 bit port we need to write here the high and ,low bytes successively LCD_PIN_WR=0; LCD_PIN_WR=1; LCD_PORT->write(Data & 0x00FF); // LSB LCD_PIN_WR=0; LCD_PIN_WR=1; LCD_PIN_CS=1; } void LCDTFT::vLCDTFTWriteData(unsigned short Data){ LCD_PIN_RS=1; LCD_PIN_CS=0; LCD_PORT->write(Data>>8); // MSB so with an 8 bit port we need to write here the high and ,low bytes successively LCD_PIN_WR=0; LCD_PIN_WR=1; LCD_PORT->write(Data & 0x00FF); // LSB LCD_PIN_WR=0; LCD_PIN_WR=1; LCD_PIN_CS =1; } void LCDTFT::vLCDTFTWriteCommandData(unsigned short CMD,unsigned short Data){ vLCDTFTWriteCommand(CMD); vLCDTFTWriteData(Data); } void LCDTFT::vLCDTFTAddressSet(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2){ vLCDTFTWriteCommandData(0x0044,(x2<<8)+x1); vLCDTFTWriteCommandData(0x0045,y1); vLCDTFTWriteCommandData(0x0046,y2); vLCDTFTWriteCommandData(0x004e,x1); vLCDTFTWriteCommandData(0x004f,y1); vLCDTFTWriteCommand(0x0022); } void LCDTFT::vLCDTFTAddressSetPoint(unsigned short x,unsigned short y){ // CGRAM addresses are given by (x+y*256) - for some reason the y cordinate // addresses require 17 bits // equiv if y is given by 0xYYY and x by 0xXX // then address of point x,y is 0xYYYXXX int add; int adl,adh; if(orient==0){ // portrait add=x+y*256; //240 x 320 y but 256 bytes for each x row } else{ add=(239-y)+x*256; } adl=add & 0x00FF; // selects the 8 low bits adh=(add >>8); // the 9 high bits vLCDTFTWriteCommandData(0x0020,adl); // 8 lsb of address vLCDTFTWriteCommandData(0x0021,adh); //9 msb of address vLCDTFTWriteCommand(0x0022); // prepare to send rgb data } void LCDTFT::vLCDTFTInit(bool format){ int i; unsigned short address,data; orient=format; LCD_PIN_RESET=1; wait_ms(5); // must hold for at least 1ms after reset LCD_PIN_RESET=0; wait_ms(10); // wait for stable R-C oscillation LCD_PIN_RESET=1; wait_ms(5); // final wait for rest to be acitvated LCD_PIN_CS=1; LCD_PIN_RD=1; LCD_PIN_WR=1; wait_ms(20); for(i=0;i<sizeof(regValues)/4;i++) { address=regValues[i*2]; data=regValues[i*2+1]; if(address==0xFF) { wait_ms(data); } else { vLCDTFTWriteCommandData(address,data); } } wait_ms(1); /* vLCDTFTWriteCommandData(0x0000,0x0001); wait_ms(1); vLCDTFTWriteCommandData(0x0003,0xA8A4); wait_ms(1); vLCDTFTWriteCommandData(0x000C,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x000D,0x080C); wait_ms(1); vLCDTFTWriteCommandData(0x000E,0x2B00); wait_ms(1); vLCDTFTWriteCommandData(0x001E,0x00B0); wait_ms(1); vLCDTFTWriteCommandData(0x0001,0x2B3F); wait_ms(1); vLCDTFTWriteCommandData(0x0002,0x0600); wait_ms(1); vLCDTFTWriteCommandData(0x0010,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x0011,0x6070); wait_ms(1); vLCDTFTWriteCommandData(0x0005,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x0006,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x0016,0xEF1C); wait_ms(1); vLCDTFTWriteCommandData(0x0017,0x0003); wait_ms(1); vLCDTFTWriteCommandData(0x0007,0x0233); wait_ms(1); vLCDTFTWriteCommandData(0x000B,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x000F,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x0041,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x0042,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x0048,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x0049,0x013F); wait_ms(1); vLCDTFTWriteCommandData(0x004A,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x004B,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x0044,0xEF00); wait_ms(1); vLCDTFTWriteCommandData(0x0045,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x0046,0x013F); wait_ms(1); vLCDTFTWriteCommandData(0x0030,0x0707); wait_ms(1); vLCDTFTWriteCommandData(0x0031,0x0204); wait_ms(1); vLCDTFTWriteCommandData(0x0032,0x0204); wait_ms(1); vLCDTFTWriteCommandData(0x0033,0x0502); wait_ms(1); vLCDTFTWriteCommandData(0x0034,0x0507); wait_ms(1); vLCDTFTWriteCommandData(0x0035,0x0204); wait_ms(1); vLCDTFTWriteCommandData(0x0036,0x0204); wait_ms(1); vLCDTFTWriteCommandData(0x0037,0x0502); wait_ms(1); vLCDTFTWriteCommandData(0x003A,0x0302); wait_ms(1); vLCDTFTWriteCommandData(0x003B,0x0302); wait_ms(1); vLCDTFTWriteCommandData(0x0023,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x0024,0x0000); wait_ms(1); vLCDTFTWriteCommandData(0x0025,0x8000); wait_ms(1); vLCDTFTWriteCommandData(0x004f,0); vLCDTFTWriteCommandData(0x004e,0); vLCDTFTWriteCommand(0x0022); */ } void LCDTFT::vLCDTFTFillScreen(unsigned short Color){ unsigned short i,j; vLCDTFTWriteCommandData(0x0020,00); //set x=0 vLCDTFTWriteCommandData(0x0021,00); // set y=0 vLCDTFTWriteCommand(0x0022); for(i=0;i<320;i++){ for (j=0;j<240;j++){ vLCDTFTWriteData(Color); } } } void LCDTFT::vLCDTFTPoint(unsigned short x,unsigned short y,unsigned short Color){ vLCDTFTAddressSetPoint(x,y); vLCDTFTWriteData(Color); } void LCDTFT::vLCDTFTText(unsigned short x,unsigned short y,const char *PtrText,const char (*Fuente)[5],unsigned char Alto,unsigned short Color,unsigned short BackColor){ unsigned short i, j, k, l, m, temp; char DataPunto[5]; const char *Ptr; while(*PtrText!='\0'){ Ptr=(Fuente+*PtrText-' ')[0]; for(i=0;i<5;i++){DataPunto[i]=*Ptr++;} switch(*PtrText){ case '\n': y += 7*Alto + 1; break; case '\r': x = 0; break; default: if(x+5*Alto >= LCD_X_MAX){ x = 0; y += 7*Alto + 1; } for(j=0; j<5; ++j, x+=Alto){ for(k=0; k < 7; k++){ temp=(0x01<<k); if((DataPunto[j]&temp)==temp){ for(l=0; l < Alto; ++l){ for(m=0; m < Alto; ++m){ vLCDTFTPoint(x+m,y+k*Alto+l,Color); }//endform }//endforl }//endif else{ for(l=0; l < Alto; ++l){ for(m=0; m < Alto; ++m){ vLCDTFTPoint(x+m,y+k*Alto+l,BackColor); }//endform }//endforl } } } x++; break; } *PtrText++; } } void LCDTFT::vLCDTFTLine(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,unsigned short Color){ unsigned short dy, dx; short addx=1, addy=1; short P, diff; unsigned short i=0; diff=((short)x2-x1); if(diff<0) diff*=-1; dx=diff; diff=((short)y2-y1); if(diff<0) diff*=-1; dy=diff; if(x1 > x2)addx = -1; if(y1 > y2)addy = -1; if(dx >= dy){ dy *= 2; P = dy - dx; diff = P - dx; for(;i<=dx;++i){ vLCDTFTPoint(x1, y1, Color); if(P < 0){ P += dy; x1 += addx; }else{ P += diff; x1 += addx; y1 += addy; } } }else{ dx *= 2; P = dx - dy; diff = P - dy; for(; i<=dy; ++i){ vLCDTFTPoint(x1, y1, Color); if(P < 0){ P += dx; y1 += addy; }else{ P += diff; x1 += addx; y1 += addy; } } } } void LCDTFT::vLCDTFTRectangle(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,bool Filled,unsigned short Color){ if(Filled){ int Lenght=(int)(x2-x1); for(int i=0;i<Lenght;i++){ vLCDTFTLine(x1,y1+i,x2,y1+i,Color); } }else{ vLCDTFTLine(x1, y1, x2, y1, Color); vLCDTFTLine(x1, y2, x2, y2, Color); vLCDTFTLine(x1, y1, x1, y2, Color); vLCDTFTLine(x2, y1, x2, y2, Color); } } void LCDTFT::vLCDTFTCircle(unsigned short x,unsigned short y,unsigned short Radius,bool Filled,unsigned short Color){ short a, b, P; a = 0; b = Radius; P = 1 - Radius; do{ if(Filled){ vLCDTFTLine(x-a, y+b, x+a, y+b, Color); vLCDTFTLine(x-a, y-b, x+a, y-b, Color); vLCDTFTLine(x-b, y+a, x+b, y+a, Color); vLCDTFTLine(x-b, y-a, x+b, y-a, Color); }else{ vLCDTFTPoint(a+x, b+y, Color); vLCDTFTPoint(b+x, a+y, Color); vLCDTFTPoint(x-a, b+y, Color); vLCDTFTPoint(x-b, a+y, Color); vLCDTFTPoint(b+x, y-a, Color); vLCDTFTPoint(a+x, y-b, Color); vLCDTFTPoint(x-a, y-b, Color); vLCDTFTPoint(x-b, y-a, Color); } if(P < 0) P += 3 + 2 * a++; else P += 5 + 2 * (a++ - b--); }while(a <= b); } /* void LCDTFT::vDrawImageBMP24Bits(const char *NameImagen){ #define OffsetWidthPixel 18 #define OffsetHeighPixel 22 #define OffsetSizeFile 34 #define OffsetInitData 10 #define OffserTipeFile 28 char Nombre[80],k; unsigned short PosXImagen,PosYImagen; unsigned char Temp,BufferHeader[54],BufferTemp[3],Adicional; unsigned int WidthPixel,HeighPixel; unsigned short TipeFile,InitData,Temp16bits; union{ unsigned short Val; struct{ unsigned Blue:5; unsigned Green:6; unsigned Red:5; }; }Color; LocalFileSystem local("mbedMemory"); sprintf(&Nombre[0],"/mbedMemory/"); k=12; while(*NameImagen!='\0'){ Nombre[k++]=*NameImagen++; } FILE *Imagen = fopen((const char *)&Nombre[0], "r"); // Abrimos archivo para lectura. // Si no se pudo encontrar archivo: if(!Imagen) { vLCDTFTFillScreen(ColorBlack); return; } // Leemos cabecera de archivo fread(&BufferHeader[0],1,54,Imagen); WidthPixel = ((unsigned int)BufferHeader[OffsetWidthPixel + 3]*16777216+BufferHeader[OffsetWidthPixel + 2]*65536+BufferHeader[OffsetWidthPixel + 1]*256+BufferHeader[OffsetWidthPixel]); HeighPixel = ((unsigned int)BufferHeader[OffsetHeighPixel + 3]*16777216+BufferHeader[OffsetHeighPixel + 2]*65536+BufferHeader[OffsetHeighPixel + 1]*256+BufferHeader[OffsetHeighPixel]); InitData = ((unsigned short)BufferHeader[OffsetInitData]); TipeFile = ((unsigned short)BufferHeader[OffserTipeFile + 1]*256 + BufferHeader[OffserTipeFile]); if((WidthPixel>LCD_X_MAX) || (HeighPixel>LCD_Y_MAX) || (TipeFile!=24)){ fclose(Imagen); return; } if(InitData!=54){ for(int k=54;k<InitData;k++){ fread(&Temp,1,1,Imagen); } } PosXImagen=(LCD_X_MAX/2)-(WidthPixel/2); PosYImagen=(LCD_Y_MAX/2)+(HeighPixel/2); Temp16bits=WidthPixel*3; Adicional=0; while(((Temp16bits)%4)!=0){ Adicional++; Temp16bits++; } for(int k=0,y=PosYImagen;k<HeighPixel;k++,y--){ vLCDTFTAddressSet(PosXImagen,y,PosXImagen+WidthPixel-1,y); for(int i=0;i<WidthPixel;i++){ fread(&BufferTemp[0],1,3,Imagen); // Leemos 3 bytes (R,G,B) Color.Blue=BufferTemp[0]>>3;Color.Green=BufferTemp[1]>>2;Color.Red=BufferTemp[2]>>3; // Conversion de 24-bits a 16-bits.- vLCDTFTWriteData(Color.Val); } // Bytes adicionales para que linea sea multiplo de 4.- for(int p=0;p<Adicional;p++){ fread(&Temp,1,1,Imagen); } } fclose(Imagen); } */ void LCDTFT::vLCDTFTDrawImage(unsigned short x,unsigned short y, unsigned short Width, unsigned short Heigh, unsigned int Lenght, const unsigned short *Imagen){ vLCDTFTAddressSet(x,y,x+Width-1,y+Heigh-1); for(int i=0;i<Lenght;i++){ vLCDTFTWriteData(*Imagen++); } }