T6963c Graphic LCD

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

T6963c Graphic LCD

1,701 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Blogs on Mon Jun 04 20:47:59 MST 2012
Hi does anyone have any source codes for running Toshiba T6963c graphic display with ARM chips?

I have been trying to adjust an AVR version of the source code but so far have yet to get it working.

Here's the code I have so far. I am not sure whether the "outByte" function is correct though.

#define T6963_WR(1 << 9)
#define T6963_RD(1 << 8)
#define T6963_CE(1 << 7)
#define T6963_CD(1 << 6)
#define T6963_RESET(1 << 1)

#define T6963_D0(1 << 18)
#define T6963_D1(1 << 17)
#define T6963_D2(1 << 15)
#define T6963_D3(1 << 16)
#define T6963_D4(1 << 23)
#define T6963_D5(1 << 24)
#define T6963_D6(1 << 25)
#define T6963_D7(1 << 26)

#define GLCD_NUMBER_OF_LINES64
#define GLCD_PIXELS_PER_LINE240
#define GLCD_FONT_WIDTH6

#define GLCD_TEXT_HOME0
#define GLCD_TEXT_AREA(GLCD_PIXELS_PER_LINE / GLCD_FONT_WIDTH)
#define GLCD_OFFSET_REGISTER2
#define GLCD_TEXT_SIZE(GLCD_TEXT_AREA * (GLCD_NUMBER_OF_LINES/8))

#define T6963_SET_TEXT_HOME_ADDRESS0x40
#define T6963_SET_TEXT_AREA0x41
#define T6963_SET_OFFSET_REGISTER0x22
#define T6963_SET_ADDRESS_POINTER0x24
#define T6963_DISPLAY_MODE0x90
#define T6963_TEXT_DISPLAY_ON0x04
#define T6963_MODE_SET0x80
#define T6963_DATA_WRITE_AND_INCREMENT0xC0


void delay(void)
{
int i;
for (i = 0; i < 4; i++);
}

void outByte(unsigned char byte)
{
LPC_GPIO0->FIODIR = (0xFF << T6963_D0);
LPC_GPIO0->FIOPIN0 = ((unsigned int)(byte << T6963_D0));
}

void T6963_WriteData(int data)
{
outByte(data);

LPC_GPIO0->FIOCLR = (T6963_CE | T6963_WR | T6963_CD);
delay();
LPC_GPIO0->FIOSET = (T6963_CE | T6963_WR | T6963_CD);
}

void T6963_WriteCommand(int command)
{
outByte(command);

LPC_GPIO0->FIOCLR = (T6963_CE | T6963_WR);
delay();
LPC_GPIO0->FIOSET = (T6963_CE | T6963_WR);
}

void T6963_Init(void)
{
int i;

//Setup Port Pins
LPC_GPIO0->FIODIR = (T6963_WR | T6963_RD | T6963_CE | T6963_CD | T6963_RESET);
LPC_GPIO0->FIOSET = (T6963_WR | T6963_RD | T6963_CE | T6963_CD | T6963_RESET);

//Setup Data Pins
LPC_GPIO0->FIODIR = (T6963_D0 | T6963_D1 | T6963_D2 | T6963_D3 | T6963_D4 | T6963_D5 | T6963_D6 | T6963_D7);
LPC_GPIO0->FIOSET = (T6963_D0 | T6963_D1 | T6963_D2 | T6963_D3 | T6963_D4 | T6963_D5 | T6963_D6 | T6963_D7);

//Reset
LPC_GPIO0->FIOCLR = (T6963_RESET);
for (i = 0; i < 1000; i++);
LPC_GPIO0->FIOSET = (T6963_RESET);

T6963_WriteData(GLCD_TEXT_HOME);
T6963_WriteData(0x00);
T6963_WriteCommand(T6963_SET_TEXT_HOME_ADDRESS);

T6963_WriteData(GLCD_TEXT_AREA);
T6963_WriteData(0x00);
T6963_WriteCommand(T6963_SET_TEXT_AREA);

T6963_WriteData(GLCD_OFFSET_REGISTER);
T6963_WriteData(0x00);
T6963_WriteCommand(T6963_SET_OFFSET_REGISTER);

T6963_WriteData(0);
T6963_WriteData(0);
T6963_WriteCommand(T6963_SET_ADDRESS_POINTER);

T6963_WriteCommand(T6963_DISPLAY_MODE | T6963_TEXT_DISPLAY_ON /* T6963_CURSOR_DISPLAY_ON*/);
T6963_WriteCommand(T6963_MODE_SET | 0);
}

void T6963_ClearText(void)
{
int i;
T6963_WriteData(GLCD_TEXT_HOME);
T6963_WriteData(GLCD_TEXT_HOME >> 8);
T6963_WriteCommand(T6963_SET_ADDRESS_POINTER);

for(i = 0; i < GLCD_TEXT_SIZE; i++)
{
T6963_WriteData(0);
T6963_WriteCommand(T6963_DATA_WRITE_AND_INCREMENT);
}
}

void T6963_WriteChar(char ch)
{
T6963_WriteData(ch - 32);
T6963_WriteCommand(T6963_DATA_WRITE_AND_INCREMENT);
}

void T6963_TextGoTo(int x, int y)
{
int address;

address = GLCD_TEXT_HOME + x + (GLCD_TEXT_AREA * y);

T6963_WriteData(address);
T6963_WriteData(address >> 8);
T6963_WriteCommand(T6963_SET_ADDRESS_POINTER);
}

void T6963_WriteString(char *str)
{
while(*str)
{
T6963_WriteChar(*str++);
}
}

int main(void) {
LPC_GPIO0->FIODIR = 1 << 11;
LPC_GPIO0->FIOSET = 1 << 11;

int j;

T6963_Init();
T6963_ClearText();

T6963_TextGoTo(13, 3);
T6963_WriteString("TOSHIBA T6963C");

LPC_GPIO0->FIOCLR = 1 << 11;

while(1);

return 0;
}
0 Kudos
Reply
4 Replies

1,526 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by tbajur on Sat Sep 15 13:37:00 MST 2012
Hi, i'm sorry for put this topic up again...
but i'm try make my our library have some weeks... this code works ( with the changes mentioned ) ?:p
0 Kudos
Reply

1,526 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Blogs on Mon Jun 18 18:07:14 MST 2012
Hi there, I've been trying to get the T6963c Graphic Display to work on the LPC1769 LPCXpresso development board. I adapted the code from this website: http://en.radzio.dxp.pl/t6963/arm/at91.htm
I then changed the parameters to fit the LPC1769. However I am still unable to make it show words on the screen.

Here is my code I have so far.

[Code]
#define T6963_WR(1 << 8)
#define T6963_RD(1 << 9)
#define T6963_CE(1 << 6)
#define T6963_CD(1 << 7)
#define T6963_RESET(1 << 0)

#define T6963_ST0(1 << 17)
#define T6963_ST1(1 << 18)
#define T6963_ST2(1 << 16)
#define T6963_ST3(1 << 15)
#define T6963_ST4(1 << 24)
#define T6963_ST5(1 << 23)
#define T6963_ST6(1 << 26)
#define T6963_ST7(1 << 25)

#define T6963_ST0_IN(0 << 17)
#define T6963_ST1_IN (0 << 18)
#define T6963_ST2_IN(0 << 16)
#define T6963_ST3_IN(0 << 15)
#define T6963_ST4_IN(0 << 24)
#define T6963_ST5_IN(0 << 23)
#define T6963_ST6_IN(0 << 26)
#define T6963_ST7_IN(0 << 25)

#define GLCD_NUMBER_OF_LINES64
#define GLCD_PIXELS_PER_LINE240
#define GLCD_FONT_WIDTH6

#define GLCD_TEXT_HOME0
#define GLCD_TEXT_AREA(GLCD_PIXELS_PER_LINE / GLCD_FONT_WIDTH)
#define GLCD_OFFSET_REGISTER2
#define GLCD_TEXT_SIZE(GLCD_TEXT_AREA * (GLCD_NUMBER_OF_LINES/8))

#define T6963_SET_TEXT_HOME_ADDRESS0x40
#define T6963_SET_TEXT_AREA0x41
#define T6963_SET_OFFSET_REGISTER 0x22
#define T6963_SET_ADDRESS_POINTER0x24
#define T6963_DISPLAY_MODE 0x90
#define T6963_TEXT_DISPLAY_ON0x04
#define T6963_MODE_SET0x83
#define T6963_DATA_WRITE_AND_INCREMENT0xC0

volatile uint32_t msTicks;

void SysTick_Handler(void)
{
msTicks++;
}

void delay (uint32_t delayTicks)
{
uint32_t currentTicks;

currentTicks = msTicks;

while((msTicks - currentTicks) < delayTicks);
}

void Reset()
{
int i;
LPC_GPIO0->FIOCLR = (T6963_RESET);
for (i = 0; i < 1000; i++);
LPC_GPIO0->FIOSET = (T6963_RESET);
}

void outByte(unsigned char output)
{
switch (output)
{
case 0x00:
LPC_GPIO0->FIOCLR = (T6963_ST0 | T6963_ST1 | T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST5 | T6963_ST6 | T6963_ST7);
break;

case 0x40:
LPC_GPIO0->FIOCLR = (T6963_ST0 | T6963_ST1 | T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST5 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST6);
break;

case 0x28:
LPC_GPIO0->FIOCLR = (T6963_ST0 | T6963_ST1 | T6963_ST2 | T6963_ST4 | T6963_ST6 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST3 | T6963_ST5);
break;

case 0x41:
LPC_GPIO0->FIOCLR = (T6963_ST1 | T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST5 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST0 | T6963_ST6);
break;

case 0x02:
LPC_GPIO0->FIOCLR = (T6963_ST0 | T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST5 | T6963_ST6 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST1);
break;

case 0x22:
LPC_GPIO0->FIOCLR = (T6963_ST0 | T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST6 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST1 | T6963_ST5);
break;

case 0x24:
LPC_GPIO0->FIOCLR = (T6963_ST0 | T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST5 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST1 | T6963_ST6);
break;

case 0x94:
LPC_GPIO0->FIOCLR = (T6963_ST0 | T6963_ST1 | T6963_ST3 | T6963_ST5 | T6963_ST6);
LPC_GPIO0->FIOSET = (T6963_ST2 | T6963_ST4 | T6963_ST7);
break;

case 0x83:
LPC_GPIO0->FIOCLR = (T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST5 | T6963_ST6);
LPC_GPIO0->FIOSET = (T6963_ST0 | T6963_ST1 | T6963_ST7);
break;

case 0xC0:
LPC_GPIO0->FIOCLR = (T6963_ST0 | T6963_ST1 | T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST5);
LPC_GPIO0->FIOSET = (T6963_ST6 | T6963_ST7);
break;

case 0x33:
LPC_GPIO0->FIOCLR = (T6963_ST2 | T6963_ST3 | T6963_ST6 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST0 | T6963_ST1 | T6963_ST4 | T6963_ST5);
break;

case 0x34:
LPC_GPIO0->FIOCLR = (T6963_ST0 | T6963_ST1 | T6963_ST3 | T6963_ST6 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST2 | T6963_ST4 | T6963_ST5);
break;

case 0x85:
LPC_GPIO0->FIOCLR = (T6963_ST1 | T6963_ST3 | T6963_ST4 | T6963_ST5 | T6963_ST6);
LPC_GPIO0->FIOSET = (T6963_ST0 | T6963_ST2 | T6963_ST7);
break;

case 0x80:
LPC_GPIO0->FIOCLR = (T6963_ST0 | T6963_ST1 | T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST5 | T6963_ST6);
LPC_GPIO0->FIOSET = (T6963_ST7);
break;

case 0x13:
LPC_GPIO0->FIOCLR = (T6963_ST2 | T6963_ST3 | T6963_ST5 | T6963_ST6 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST0 | T6963_ST1 | T6963_ST4);
break;

case 0x16:
LPC_GPIO0->FIOCLR = (T6963_ST0 | T6963_ST3 | T6963_ST5 | T6963_ST6 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST1 | T6963_ST2 | T6963_ST4);
break;

case 0x19:
LPC_GPIO0->FIOCLR = (T6963_ST1 | T6963_ST2 | T6963_ST5 | T6963_ST6 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST0 | T6963_ST3 | T6963_ST4);
break;

case 0x21:
LPC_GPIO0->FIOCLR = (T6963_ST1 | T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST6 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST0 | T6963_ST5);
break;

case 0x23:
LPC_GPIO0->FIOCLR = (T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST6 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST0 | T6963_ST1 | T6963_ST5);
break;

case 0x29:
LPC_GPIO0->FIOCLR = (T6963_ST1 | T6963_ST2 | T6963_ST4 | T6963_ST6 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST0 | T6963_ST3 | T6963_ST5);
break;

case 0x2F:
LPC_GPIO0->FIOCLR = (T6963_ST4 | T6963_ST6 | T6963_ST7);
LPC_GPIO0->FIOSET = (T6963_ST0 | T6963_ST1 | T6963_ST2 | T6963_ST3 | T6963_ST5);
break;
}
}

unsigned char inByte(void)
{
uint16_t temp;

LPC_GPIO0->FIODIR = (T6963_ST0_IN | T6963_ST1_IN | T6963_ST2_IN | T6963_ST3_IN | T6963_ST4_IN | T6963_ST5_IN | T6963_ST6_IN | T6963_ST7_IN);
delay(1);
LPC_GPIO0->FIOMASK =~ (T6963_ST0 | T6963_ST1 | T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST5 | T6963_ST6 | T6963_ST7);

temp = ((LPC_GPIO0->FIOPIN) >> 15);

delay(1);
LPC_GPIO0->FIODIR = (T6963_ST0 | T6963_ST1 | T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST5 | T6963_ST6 | T6963_ST7);

return temp;
}

int T6963_CheckStatus(void)
{
int tmp;
LPC_GPIO0->FIOCLR = (T6963_CE | T6963_RD);
tmp = inByte();
LPC_GPIO0->FIOSET = (T6963_CE | T6963_RD);

return tmp;
}
void T6963_WriteData(int data)
{
while(!(T6963_CheckStatus() & 0x006));

outByte(data);
LPC_GPIO0->FIOCLR = (T6963_CE | T6963_WR | T6963_CD);
delay(1);
LPC_GPIO0->FIOSET = (T6963_CE | T6963_WR | T6963_CD);
}

void T6963_WriteCommand(int command)
{
while(!(T6963_CheckStatus() & 0x006));

outByte(command);
LPC_GPIO0->FIOCLR = (T6963_CE | T6963_WR);
delay(1);
LPC_GPIO0->FIOSET = (T6963_CE | T6963_WR);
}

void T6963_Init(void)
{
printf ("Inside T6963_Init()\n");

//Setup Pin Functions
LPC_PINCON->PINSEL0 = 0x00000000;

//Setup Pull Down resistors
//LPC_PINCON->PINMODE_OD0 = 0x00000000;
LPC_PINCON->PINMODE_OD0 = (T6963_WR | T6963_RD | T6963_CE | T6963_CD | T6963_RESET);
LPC_PINCON->PINMODE_OD0 = (T6963_ST0 | T6963_ST1 | T6963_ST2 | T6963_ST3 | T6963_ST4 | T6963_ST5 | T6963_ST6 | T6963_ST7);

//Setup Port Pins
LPC_GPIO0->FIODIR = (T6963_WR | T6963_RD | T6963_CE | T6963_CD | T6963_RESET);
LPC_GPIO0->FIOSET = (T6963_WR | T6963_RD | T6963_CE | T6963_CD | T6963_RESET);

Reset();

T6963_WriteData(GLCD_TEXT_HOME);
T6963_WriteData(0x00);
T6963_WriteCommand(T6963_SET_TEXT_HOME_ADDRESS);

T6963_WriteData(GLCD_TEXT_AREA);
T6963_WriteData(0x00);
T6963_WriteCommand(T6963_SET_TEXT_AREA);

T6963_WriteData(GLCD_OFFSET_REGISTER);
T6963_WriteData(0x00);
T6963_WriteCommand(T6963_SET_OFFSET_REGISTER);

T6963_WriteData(0x00);
T6963_WriteData(0x00);
T6963_WriteCommand(T6963_SET_ADDRESS_POINTER);

T6963_WriteCommand(T6963_DISPLAY_MODE | T6963_TEXT_DISPLAY_ON);

T6963_WriteCommand(T6963_MODE_SET | 0);
}

void T6963_ClearText(void)
{
int i;
T6963_WriteData(GLCD_TEXT_HOME);
T6963_WriteData(GLCD_TEXT_HOME >> 8);
T6963_WriteCommand(T6963_SET_ADDRESS_POINTER);

for(i = 0; i < GLCD_TEXT_SIZE; i++)
{
T6963_WriteData(0x00);
T6963_WriteCommand(T6963_DATA_WRITE_AND_INCREMENT);
}
}

void T6963_TextGoTo(int x, int y)
{
int address;

address = (GLCD_TEXT_HOME + x + (GLCD_TEXT_AREA * y));
printf("address = %X", address);
T6963_WriteData(address);
T6963_WriteData(address >> 8);
T6963_WriteCommand(T6963_SET_ADDRESS_POINTER);
}

void T6963_WriteString(char *str)
{
while(*str)
{
T6963_WriteChar(*str++);
}
}

void T6963_WriteChar(char ch)
{
T6963_WriteData(ch-32);
T6963_WriteCommand(T6963_DATA_WRITE_AND_INCREMENT);
}

int main(void) {

if (SysTick_Config(SystemCoreClock/1000000))
{
printf("in SysTick_Config");
while(1);
}
T6963_Init();

T6963_ClearText();
while (1)
{
printf("beginning\n");
T6963_TextGoTo(13, 3);
T6963_WriteString("TOSHIBA T6963");
printf("end\n");
}
return 0 ;
}
[/Code]

Any suggestions in what I am doing wrong? Any sort of help will be useful.

Thanks
0 Kudos
Reply

1,526 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by js-nxp on Tue Jun 05 00:08:32 MST 2012
Darn :) tried to fix the CODE tags forgetting I'm not a moderator here.
0 Kudos
Reply

1,526 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Mon Jun 04 22:02:59 MST 2012
Please use the [ CODE ] tags when posting code (the "#"button on the button bar of the editor) that makes thing that much easier to read and keeps proper indentations.
Or just type in the codes by hand: [ CODE ] and [ /CODE ] (without the spaces) - I really wished there was a sticky readme for newcomers on this forum :eek:

Then you'd see thinks like:

void delay(void)
{
    int i;
    for (i = 0; i < 4; i++);
}

void outByte(unsigned char byte)
{
    LPC_GPIO0->FIODIR = (0xFF << T6963_D0);
    LPC_GPIO0->FIOPIN0 = ((unsigned int)(byte << T6963_D0));
}
First of all, the delay loop will be optimized away when you use optimizations. You'll need to find some other way to create a delay - try the systick - there is a nice example in the examples that come with the software.

Secondly, on my LPC1xxx there are no 8 consecutive bits on P0 - it might be good if you told us which LPCxxxx variant you are using.

And; the outByte function sets the P0 direction bits but it does not set the _WR signal - that you only do in the _WriteData and _WriteCommand functions and at the wrong place ... For clarity I would just place those two lines of codes from outByte in the _Writexxxx functions. Function call overhead is most likely almost as large as the duplication of the code (maybe even larger).

On these types of buses you always first set the _WR signal and only then make the port an output. Having _WR high while making your port output may create a collision between the two sides of the bus.

I did not check the specs of the display but you should make sure that you follow the proper timing. Some chips require that CE becomes low a few ns before applying the RD or WR pulse. And (again delay/timing) your delay may be too short when you are using a default 100 MHz CCLK setup.
How long should the timing of your read/write cycle be?
And on most controllers you must check some kind of status to see if the controller is ready to accept a new command or data.

Use a scope or logic analyzer to check your signals.

Rob
0 Kudos
Reply