Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: receiver TFT_CJS_ssd0139 poster8x8_ranger
Fork of LCDTFT by
LCDTFT.cpp
- Committer:
- cstevens
- Date:
- 2015-06-09
- Revision:
- 5:d910bf3b7bb0
- Parent:
- 4:2feb189748f7
File content as of revision 5:d910bf3b7bb0:
/*
@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. ////
//// ////
//// ////
///////////////////////////////////////////////////////////////////////////
//
//NB May 2015
// because this uses BusOut its not really very quick. would be better to use PortOut which
// is generally a lot faster - typical exmaple max speed Busout=168kHz whereas PortOut=2470kHz - >10xfaster!
// will try to re-write this sometime for this kind of access but will be a pain due to the pinning
// of the paralell TFTLCD
/*
TFTLCD module pin------KL25Z matching pi
LCD_D0 PTA13
LCD_D1 PTD5
LCD_D2 PTD4
LCD_D3 PTA12
LCD_D4 PTA$
LCD_D5 PTA5
LCD_D6 PTC8
LCD_D7 PTC9
*/
// so hard to get a single port to do this 8 bit interface.... but could use PTC 0 3 4 5 6 7 8 9 by masking out PTC1 and 2
// would need a separate pcb to hold the screen...
//can't be stripboard thanks to stupid arduino pins
#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,lmax;
char DataPunto[5];
const char *Ptr;
if(orient==0) lmax=LCD_X_MAX;
else lmax=LCD_Y_MAX;
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 >= lmax){
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++);
}
}
