GraphicLCD library problem

24 Dec 2010

I am trying to define a library for RA6963 graphic chip and started out with a simple init function.   When I try to declare the pins struct, I get this compiler warning

Members and base classes will be initialized in declaration order, not in member initialization list order
for the following code:

GraphicLCD::GraphicLCD(PinName CD, PinName RD, PinName WD
        , PinName d0, PinName d1, PinName d2, PinName d3
        , PinName d4, PinName d5, PinName d6, PinName d7
        , PinName CE) : 
        _CD(CD), _RD(RD), _WD(WD), _D(d0, d1, d2, d3, d4, d5, d6, d7),_CE(CE){

I then get another error

undefined symbol vtable for GraphicLCD(referred from GraphicLCD.cpp.cpp.LPC1768.o).(EL6218E)
that doesn't point to any specific line.  Where should I look to identify the cause of these errors?

24 Dec 2010

I got the same error for the first one. Just swap the order of the pins so it's consistent on both .cpp and .h files. So, on your class declaration use DigitalOut CD,DigitalOut RD,....

25 Dec 2010

Oddly, everything looks the same to me.

 

GraphicLCD.cpp

GraphicLCD::GraphicLCD(PinName CD, PinName RD, PinName WD
        , PinName d0, PinName d1, PinName d2, PinName d3
        , PinName d4, PinName d5, PinName d6, PinName d7
        , PinName CE) : 
        _CD(CD), _RD(RD), _WD(WD), _D(d0, d1, d2, d3, d4, d5, d6, d7),_CE(CE){ 
GraphicLCD.h

       
    GraphicLCD(PinName CD, PinName RD, PinName WD
        , PinName d0, PinName d1, PinName d2, PinName d3
        , PinName d4, PinName d5, PinName d6, PinName d7
        , PinName CE);
Do you see any differences I don't understand maybe?

25 Dec 2010

When you declare the variables:

 

private:

DigitalOut CD;

..

..

DigitalOut CE

This has to be in the same order as the declaration on the constructor on both the .h and .cpp. It's not that important anyways, it will still work fine.

No idea about the second though, without looking at the code.

25 Dec 2010

Most of my code is commented out, just enough in there to be able to try and init the screen..

 

I figured out the first error, but still have that undefined vtable now...

GraphicLCD.cpp:

#include "GraphicLCD.h"
#include "mbed.h"

GraphicLCD::GraphicLCD(PinName CD, PinName RD, PinName WD
        , PinName d0, PinName d1, PinName d2, PinName d3
        , PinName d4, PinName d5, PinName d6, PinName d7
        , PinName CE) : 
        _CD(CD), _RD(RD), _WD(WD), _D(d0, d1, d2, d3, d4, d5, d6, d7),_CE(CE){//,_type(type) {
    wait(0.020);//  wait for display to power up
//write text home address =0,0
    writeData(0x00);
    writeData(0x00);
    writeCommand(0x40);

    writeData(0x80);
    writeData(0x00);
    writeCommand(0x42);
   //write text area address
    writeData(0x10);
    writeData(0x00);
    writeCommand(0x41);
    //write graphic area address
    writeData(0x10);
    writeData(0x00);
    writeCommand(0x43);
    //display text and graphics modes
    writeCommand(0x9c);
    //enable display
    writeCommand(0x98);

 }
void GraphicLCD::writeByte(int value) {
//CD (SHOULD ALREADY BE SET BEFORE COMING HERE
//SETUP TIME 20ns
wait(0.000020f); //wait 20ns
_CE=1;
//CE
_WD=1;
//RD OR WD
_D=value;
//DATA
wait(0.000080f);//wait 80ns
//HOLD 80ns
_CE=0;
//CE OFF
_WD = 0;
//RD OFF
wait(0.000040f);
//WAIT 40ns
}
void GraphicLCD::writeCommand(int command) {
    _CD = 0;
    writeByte(command);
}

void GraphicLCD::writeData(int data) {
    _CD = 1;
    writeByte(data);
}
GraphicLCD.h

#ifndef MBED_GraphicLCD_h
#define MBED_GraphicLCD_h

#include "mbed.h"
class GraphicLCD : public Stream {
public:
    GraphicLCD(PinName CD, PinName RD, PinName WD
        , PinName d0, PinName d1, PinName d2, PinName d3
        , PinName d4, PinName d5, PinName d6, PinName d7
        , PinName CE);//, LCDType type = LCD128x64);

#if DOXYGEN_ONLY
    int putc(int c);
    int printf(const char* format, ...);
#endif
    int rows();
    int columns();

protected:

    // Stream implementation functions
    virtual int _putc(int value);
    virtual int _getc();
    void writeByte(int value);
    void writeCommand(int command);
    void writeData(int data);

    DigitalOut _CD, _RD, _WD;//CE was defined here.  moved to row below _D to match the initialization order
    BusOut _D;
     DigitalOut _CE;
    int _column;
    int _row;
};

#endif
Main.cpp

#include "mbed.h"
#include "GraphicLCD.h"

 GraphicLCD lcd(p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16);
 
DigitalOut myled(LED1);

int main() {
      lcd.printf("Hello World!\n");

    while(1) {
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }
}

25 Dec 2010

Well mine is based on a KS0108 so i can't test this but first thing i did after writing the driver function was to implement the SetPixel function.

In this case  I suspect the problem is with the printf function. even though you have implemented the putc it wont work that way. to see if you get anything on screen i would do something like

for(int i =0;i<128;i++){

lcd.writeData(i); or lcd.writebyte();

}

I would try the putc function first. If you get anything on screen it means you have initialized it correctly. I see that your chip is based on the Toshiba controller so the printf is kinda of different from mine since for the KS0108 you'll have to implement it in software.

Give it a try see what you get.

25 Dec 2010

 

user Daniel Near wrote:
I then get another error
undefined symbol vtable for GraphicLCD(referred from GraphicLCD.cpp.cpp.LPC1768.o).(EL6218E)
that doesn't point to any specific line.  Where should I look to identify the cause of these errors?

This error shows up when your inherited class misses to define a method marked as 'pure virtual'. Such methods are declared as 'virtual xx xyz()=0' in the header file.

For the Stream class, there two such methods: _putc() and _getc().

 

25 Dec 2010

user Hendrik Lipka wrote:

 

user Daniel Near wrote:
I then get another error
undefined symbol vtable for GraphicLCD(referred from GraphicLCD.cpp.cpp.LPC1768.o).(EL6218E)
that doesn't point to any specific line.  Where should I look to identify the cause of these errors?

This error shows up when your inherited class misses to define a method marked as 'pure virtual'. Such methods are declared as 'virtual xx xyz()=0' in the header file.

For the Stream class, there two such methods: _putc() and _getc().

 

Ok.  I at least resolved the compiler conflict by adding this to my GraphicLCD.cpp

int GraphicLCD::_putc(int value) {
    return -1;
}int GraphicLCD::_getc() {
    return -1;
}
After I get things running, I'll worry about implementing them 'correctly'..

24 Jan 2011

Gents,

I've been trying to get a Optrex DFM5001N 160x128 display running on an Mbed using this code. It is based on the T6963C chip and although I can get the display to work on a PIC16F877, it will not display on the Mbed. In my readings, it looks like I need to check the status of the display after I send out various commands and bytes but this code does not use any status checking. I wonder, am I missing something? I've tried 50ms delays to mimic the status reads but to no avail.

Can anybody offer more suggestions? I'll keep attacking the problem...one step a time.

Thanks, AP

24 Jan 2011

I got this to work on Arduino with a sketch I found there. I haven't had much time to port it to Mbed and get it working here.

The code below has some oddities such as stretching the d0-d7 pins across two ports, as the Arduino doesn't have much for contiguous pins on one port. But otherwise, it brought my display alive and displayed both graphics and text.

T6963_main.pde

#include "T6963.h"
T6963 LCD(128,64,6,32);

void setup(){
  //Serial.begin(9600);
  //Serial.print("TH: ");
  //Serial.println(LCD.getTH());
  //Serial.print("GH: ");
  //Serial.println(LCD.getGH());
  
  LCD.Initialize();
  
 // Serial.println("Initialized");
  LCD.TextGoTo(0,0);
  LCD.WriteString("Hello World");
  
}
void loop(){
  for(byte _b = 0;_b<240;_b++){
    LCD.writePixel(_b,_b>>1,1);
  }
  for(byte _b=0;_b<128;_b +=8){
    LCD.TextGoTo(_b/8,_b/8);
    LCD.WriteString("Hello World");
  }
  delay(1000);
  LCD.clearGraphic();
  LCD.createLine(0,0,239,127);
  delay(1000);
  LCD.createLine(239,0,0,127);
  LCD.clearGraphic();
  delay(500);
  LCD.clearText();
  LCD.setPixel(0,0);
  LCD.setPixel(239,0);
  LCD.setPixel(239,127);
  LCD.setPixel(0,127);
  delay(1000);
  for(int x=0;x<128;x+=4){
    LCD.createLine(0,x,x<<1,127);
    delay(10);
  }
  delay(1000);
  LCD.createCircle(120,64,32);
  delay(1000);
  LCD.clearGraphic();
  LCD.clearText();
  
  LCD.setDispMode(true,true,true,false);
  for(byte _b=0;_b<8;_b++){
    for(byte _row = 0;_row < LCD.getTextRows();_row++){
      for(byte _col = 0;_col < LCD.getTextCols();_col++){
        LCD.setCursorPointer(_col,_row);
        delay(100);
      }
    }
    LCD.setCursorPattern(_b);
  }
  LCD.setDispMode(true,true,false,false);
}

T6963.cpp

/*-------------------------------------------------------------------------------------------------
0.0- What these 2 guys built that I worked from
      Graphic LCD with Toshiba T6963 controller
      Copyright (c) Rados�aw Kwiecie�, 2007r
      http://en.radzio.dxp.pl/t6963/
      Compiler : avr-gcc
      Modified By -Gil- to work on Arduino easily : http://domoduino.tumblr.com/
0.1- Invocable class T6963
      Commands moved to T6963_commands.h
      For some reason I don't have reset hooked up and all is working fine.
0.2- rbrsidedn
      renamed SetPixel(byte,byte,byte) -> writePixel(x,y,color)
      added setPixel(x,y)
      added clearPixel(x,y)
      added createline(x1,y1,x2,y2)
      added createCircle(x,y,radius)       
r6 - Checked in with SVN
r7 - Checked in with cursor controls added
r8 - Got 6bit font width (s/b any fonth width) working.
-----------------------------------------------------------------------------------------------*/
#include "WProgram.h"
#include "T6963.h"
#include "T6963_Commands.h"
//-------------------------------------------------------------------------------------------------
//
// Delay function
//	
//-------------------------------------------------------------------------------------------------
void n_delay(void)
{
  volatile byte i;
  for(i = 0; i < (F_CPU/1000000); i++)
  {
    asm("nop");
  }
}
//-------------------------------------------------------------------------------------------------
//
// Constructor
//	
//-------------------------------------------------------------------------------------------------

T6963::T6963(int pixHoriz,int pixVert,int fontWidth, int sizeMem){
  GLCD_NUMBER_OF_LINES = pixVert;
  GLCD_PIXELS_PER_LINE = pixHoriz;
  _FW = fontWidth;
  _GA = pixHoriz / fontWidth;	//Supercedes GLCD_GRAPHIC_AREA
  _TA = pixHoriz / fontWidth;	//Supercedes GLCD_TEXT_AREA
  _sizeMem = constrain(sizeMem,0,64); //size of attached memory in kb.
  sizeGA = _GA*pixVert;		//Supercedes GLCD_GRAPHIC_SIZE
  sizeTA = _TA*pixVert/8;	        //Supercedes GLCD_TEXT_SIZE
  setTH(0);
  setGH(0);
}
void T6963::setTH(unsigned int addr){
  _TH=addr;
} //expose _TH

unsigned int T6963::getTH(){
  return _TH;
}	//return _TH

void T6963::setGH(unsigned int addr){
  if(addr == _TH){
    _GH=_TH+sizeTA;
  }
  else{
    _GH=addr;
  }
}
unsigned int T6963::getGH(){
  return _GH;
}

byte T6963::setCursorPattern(byte _b){
  byte tmp = T6963_CURSOR_PATTERN_SELECT;
  _b=constrain(_b,0,7);
  tmp|=_b;
  writeCommand(tmp);
  return tmp;
}

byte T6963::setCursorPointer(byte _col,byte _row){
  _col=constrain(_col,0,(_TA-1));
  _row=constrain(_row,0,((GLCD_NUMBER_OF_LINES/8)-1));
  writeData(_col);
  writeData(_row);
  writeCommand(0x21); //Cursor pointer Set
}

byte T6963::getTextRows(){
  return (GLCD_NUMBER_OF_LINES/8);
}
byte T6963::getTextCols(){
  return _TA;
}
//-------------------------------------------------------------------------------------------------
//
// Ports intalization
//
//-------------------------------------------------------------------------------------------------
void T6963::InitalizeInterface(void){
  //GLCD_DATA_DDR = 0xFF;
  GLCD_DATA_DDR1 |= GLCD_DATA_MASK1;
  GLCD_DATA_DDR2 |= GLCD_DATA_MASK2;

  GLCD_CTRL_DDR = ((1 << GLCD_WR) | (1 << GLCD_RD) | (1 << GLCD_CE) | (1 << GLCD_CD));
  GLCD_CTRL_PORT |= ((1 << GLCD_WR) | (1 << GLCD_RD) | (1 << GLCD_CE) | (1 << GLCD_CD));
}
//-------------------------------------------------------------------------------------------------
//
// Reads dispay status
//
//-------------------------------------------------------------------------------------------------
byte T6963::checkStatus(void){
  uint8_t tmp;
  //GLCD_DATA_DDR = 0x00;
  GLCD_DATA_DDR1 &= ~GLCD_DATA_MASK1;
  GLCD_DATA_DDR2 &= ~GLCD_DATA_MASK2;

  GLCD_CTRL_PORT &= ~((1 << GLCD_RD) | (1 << GLCD_CE));
  n_delay();
  //tmp = GLCD_DATA_PIN;
  tmp = (GLCD_DATA_PIN1 GLCD_DATA_RSHIFT1) | (GLCD_DATA_PIN2 GLCD_DATA_RSHIFT2);
  //GLCD_DATA_DDR = 0xFF;
  GLCD_DATA_DDR1 |= GLCD_DATA_MASK1;
  GLCD_DATA_DDR2 |= GLCD_DATA_MASK2;
  GLCD_CTRL_PORT |= ((1 << GLCD_RD) | (1 << GLCD_CE));
  return tmp;
}
//-------------------------------------------------------------------------------------------------
//
// Writes instruction 
//
//-------------------------------------------------------------------------------------------------
void T6963::writeCommand(byte command){
  while(!(checkStatus()&0x03));
  // GLCD_DATA_PORT = command;
  GLCD_DATA_PORT1 &= ~GLCD_DATA_MASK1;
  GLCD_DATA_PORT1 |= (command GLCD_DATA_SHIFT1);
  GLCD_DATA_PORT2 &= ~GLCD_DATA_MASK2;
  GLCD_DATA_PORT2 |= (command GLCD_DATA_SHIFT2);

  GLCD_CTRL_PORT &= ~((1 << GLCD_WR) | (1 << GLCD_CE));
  n_delay();
  GLCD_CTRL_PORT |= ((1 << GLCD_WR) | (1 << GLCD_CE));
}

//-------------------------------------------------------------------------------------------------
//
// Writes data
//
//-------------------------------------------------------------------------------------------------
void T6963::writeData(byte data){
  while(!(checkStatus()&0x03));
  // GLCD_DATA_PORT = data;
  GLCD_DATA_PORT1 &= ~GLCD_DATA_MASK1;
  GLCD_DATA_PORT1 |= (data GLCD_DATA_SHIFT1);
  GLCD_DATA_PORT2 &= ~GLCD_DATA_MASK2;
  GLCD_DATA_PORT2 |= (data GLCD_DATA_SHIFT2);

  GLCD_CTRL_PORT &= ~((1 << GLCD_WR) | (1 << GLCD_CE) | (1 << GLCD_CD));
  n_delay();
  GLCD_CTRL_PORT |= ((1 << GLCD_WR) | (1 << GLCD_CE) | (1 << GLCD_CD));
}
//-------------------------------------------------------------------------------------------------
//
// Reads data
//
//-------------------------------------------------------------------------------------------------
byte T6963::ReadData(void){
  byte tmp;
  while(!(checkStatus()&0x03));
  //GLCD_DATA_DDR = 0x00;
  GLCD_DATA_DDR1 &= ~GLCD_DATA_MASK1;
  GLCD_DATA_DDR2 &= ~GLCD_DATA_MASK2;

  GLCD_CTRL_PORT &= ~((1 << GLCD_RD) | (1 << GLCD_CE) | (1 << GLCD_CD));
  n_delay();

  //tmp = GLCD_DATA_PIN;

  tmp = (GLCD_DATA_PIN1 GLCD_DATA_RSHIFT1) | (GLCD_DATA_PIN2 GLCD_DATA_RSHIFT2);
  GLCD_CTRL_PORT |= ((1 << GLCD_RD) | (1 << GLCD_CE) | (1 << GLCD_CD));

  //GLCD_DATA_DDR = 0xFF;

  GLCD_DATA_DDR1 |= GLCD_DATA_MASK1;
  GLCD_DATA_DDR2 |= GLCD_DATA_MASK2;
  return tmp;
}
//-------------------------------------------------------------------------------------------------
//
// Sets address pointer for display RAM memory
//
//-------------------------------------------------------------------------------------------------
void T6963::SetAddressPointer(unsigned int address){
  writeData(address & 0xFF);
  writeData(address >> 8);
  writeCommand(T6963_SET_ADDRESS_POINTER);
}
//-------------------------------------------------------------------------------------------------
//
// Clears text area of display RAM memory
//
//-------------------------------------------------------------------------------------------------
void T6963::clearText(){
  SetAddressPointer(_TH);
  for(int i = 0; i < sizeTA; i++){
    WriteDisplayData(0);
  }
}
//-------------------------------------------------------------------------------------------------
// Clears characters generator area of display RAM memory
//-------------------------------------------------------------------------------------------------
void T6963::clearCG(){
  unsigned int i=((_sizeMem/2)-1)*0x800;
  SetAddressPointer(i);
  for(i = 0; i < 256 * 8; i++){
    WriteDisplayData(0);
  }
}
//-------------------------------------------------------------------------------------------------
// Clears graphics area of display RAM memory
//-------------------------------------------------------------------------------------------------
void T6963::clearGraphic(){
  SetAddressPointer(_GH);
  for(unsigned int i = 0; i < sizeGA; i++){
    WriteDisplayData(0x00);
  }
}
//-------------------------------------------------------------------------------------------------
// Writes a single character (ASCII code) to display RAM memory
//-------------------------------------------------------------------------------------------------
void T6963::WriteChar(char charCode)
{
  WriteDisplayData(charCode - 32);
}
//-------------------------------------------------------------------------------------------------
// Writes null-terminated string to display RAM memory
//-------------------------------------------------------------------------------------------------
void T6963::WriteString(char * string){
  while(*string){
    WriteChar(*string++);
  }
}
//-------------------------------------------------------------------------------------------------
// Writes null-terminated string from program memory to display RAM memory
//-------------------------------------------------------------------------------------------------
void T6963::WriteStringPgm(prog_char * string){
  char ch;
  while((ch = pgm_read_byte(string++))){
    WriteChar(ch);
  }
}
//-------------------------------------------------------------------------------------------------
// Sets display coordinates
//-------------------------------------------------------------------------------------------------
void T6963::TextGoTo(unsigned char x, unsigned char y){
  unsigned int address;
  address = _TH +  x + (_TA * y);
  SetAddressPointer(address);
}
//-------------------------------------------------------------------------------------------------
// Writes single char pattern to character generator area of display RAM memory
//-------------------------------------------------------------------------------------------------
void T6963::DefineCharacter(byte charCode, unsigned char * defChar){
  unsigned int address=((_sizeMem/2)-1)*0x800;
  SetAddressPointer(address);
  for(byte i = 0; i < 8 ; i++){
    WriteDisplayData(*(defChar + i));
  }
}

//-------------------------------------------------------------------------------------------------
// Set (if color==1) or clear (if color==0) pixel on screen
//-------------------------------------------------------------------------------------------------
void T6963::writePixel(byte x, byte y, byte color){
  unsigned char tmp;
  unsigned int address;
  address = _GH + (x / _FW) + (_GA * y);
  SetAddressPointer(address);
  writeCommand(T6963_DATA_READ_AND_NONVARIABLE);
  tmp = ReadData();
  if(color){
    tmp |= (1 <<  (_FW - 1 - (x % _FW)));
  }
  else{
    tmp &= ~(1 <<  (_FW - 1 - (x % _FW)));
  }
  WriteDisplayData(tmp);
}
//-------------------------------------------------------------------------------------------------
// Set a single pixel at x,y (in pixels) to 1 (on)
//-------------------------------------------------------------------------------------------------
byte T6963::setPixel(byte x, byte y){
  SetAddressPointer((_GH + (x / _FW) + (_GA * y)));
  byte tmp=B11111000;
  tmp |= (_FW-1)-(x%_FW); //LSB Direction Correction
  writeCommand(tmp);
  return tmp;
}
//-------------------------------------------------------------------------------------------------
// Set a single pixel at x,y (in pixels) to 0 (off)
//-------------------------------------------------------------------------------------------------
byte T6963::clearPixel(byte x, byte y){
  SetAddressPointer((_GH + (x / _FW) + (_GA * y)));
  byte tmp=B11110000;
  tmp |= ((_FW-1)-(x%_FW)); //LSB Direction Correction
  writeCommand(tmp);
  return tmp;
} 
//-------------------------------------------------------------------------------------------------
// Writes display data and increment address pointer
//-------------------------------------------------------------------------------------------------
void T6963::WriteDisplayData(byte x){
  writeData(x);
  writeCommand(T6963_DATA_WRITE_AND_INCREMENT);
}
//-------------------------------------------------------------------------------------------------
// Sets graphics coordinates
//-------------------------------------------------------------------------------------------------
void T6963::GraphicGoTo(byte x, byte y){
  unsigned int address;
  address = _GH + (x / _FW) + (_GA * y);
  SetAddressPointer(address);
}
//-------------------------------------------------------------------------------------------------
// Displays bitmap from program memory
//-------------------------------------------------------------------------------------------------
/*
void T6963::Bitmap(unsigned char * bitmap, byte x, byte y, byte width, unsigned char height){
 unsigned char i, j;
 for(j = 0; j < height; j++){
 GraphicGoTo(x, y + j);
 for(i = 0; i < width/_FW; i++){
 WriteDisplayData(pgm_read_byte(bitmap + i + (_GA * j)));
 }
 }
 }
 */
byte T6963::setMode(char _mode, char _CG){
  byte tmp = T6963_MODE_SET;
  if(_mode=='X' || _mode =='x' || _mode=='^'){
    tmp |= 1;
  }
  else if(_mode == 'A' || _mode=='&' ||_mode=='a'){
    tmp |= 3;
  }
  else if(_mode == 'T'||_mode=='t'){
    tmp |=4;
  }
  else{
    tmp |= 0; //OR mode default
  }
  if(_CG =='E'||_CG=='e'){
    tmp |=8;
  }
  else{
    tmp |=0;
  }
  writeCommand(tmp);
  return tmp;
}

byte T6963::clearDispMode(){
  writeCommand(T6963_DISPLAY_MODE);
}
byte T6963::setDispMode(boolean _text,boolean _graphics, boolean _cursor, boolean _blink){
  byte tmp=T6963_DISPLAY_MODE;
  if(_graphics){
    tmp |= B1000; //T6963_GRAPHIC_DISPLAY_ON
  }
  if(_text){
    tmp |= B0100; //T6963_TEXT_DISPLAY_ON
  }
  if(_cursor){
    tmp |= B0010; //T6963_CURSOR_DISPLAY_ON
  }
  if(_blink){
    tmp |=B0001; //T6963_CURSOR_BLINK_ON
  }
  writeCommand(tmp);
  return tmp;
}
/*------------------------------------------------------------------------
Geometric shapes, scavenged from online resources.
why re-invent the wheel
*/

void T6963::createLine(int x0,int y0,int x1,int y1){
/*BreshenhamLine algorithm - From wikipedia so it must be right
http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
*/
  boolean steep = abs(y1 - y0) > abs(x1 - x0);
  if(steep){
    //swap(x0, y0)
    //swap(x1, y1)
    int tmp=x0;
    x0=y0;
    y0=tmp;
    tmp=x1;
    x1=y1;
    y1=tmp;
  }
  if(x0 > x1){
    //swap(x0, x1)
    //swap(y0, y1)
    int tmp=x0;
    x0=x1;
    x1=tmp;
    tmp=y0;
    y0=y1;
    y1=tmp;
  }
  int deltax = x1 - x0;
  int deltay = abs(y1 - y0);
  int error = deltax / 2;
  int ystep=-1;
  int y = y0;
  if(y0 < y1){ystep= 1;}
  for(int x =x0;x<=x1;x++){
    if(steep){setPixel(y,x);}else{setPixel(x,y);}
    error = error - deltay;
    if(error < 0){
      y = y + ystep;
      error = error + deltax;
    }
  }
}
/*------------------------------------------------------------------------------------------------
Circles: http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
------------------------------------------------------------------------------------------------*/

void T6963::createCircle(int cx, int cy, int radius) //cx and cy mark the distance from the origin point.
{
	int error = -radius;
	int x = radius;
	int y = 0;
 
	while (x >= y){
		plot8points(cx, cy, x, y);
 
		error += y;
		++y;
		error += y;
 
		if (error >= 0){
			--x;
			error -= x;
			error -= x;
		}
	}
}
 
void T6963::plot8points(int cx, int cy, int x, int y)
{
	plot4points(cx, cy, x, y);
	if (x != y) plot4points(cx, cy, y, x);
}
 
void T6963::plot4points(int cx, int cy, int x, int y)
{
	setPixel(cx + x, cy + y);
	if (x != 0) setPixel(cx - x, cy + y);
	if (y != 0) setPixel(cx + x, cy - y);
	if (x != 0 && y != 0) setPixel(cx - x, cy - y);
}



//-------------------------------------------------------------------------------------------------
//
// Display initalization
//
//-------------------------------------------------------------------------------------------------
void T6963::Initialize(void){
  //Set up data and control ports
  InitalizeInterface();

  //reset LCD, should be able to have hardware solution
  //GLCD_CTRL_PORT &= ~(1 << GLCD_RESET);
  //_delay_ms(1);
  //GLCD_CTRL_PORT |= (1 << GLCD_RESET);

  //Set Graphics Home Address
  writeData(_GH & 0xFF);
  writeData(_GH >> 8);
  writeCommand(T6963_SET_GRAPHIC_HOME_ADDRESS);

  //Set Graphics Area
  writeData(_GA);
  writeData(0x00);
  writeCommand(T6963_SET_GRAPHIC_AREA);

  //Set Text home address
  writeData(_TH & 0xFF);
  writeData(_TH >> 8);
  writeCommand(T6963_SET_TEXT_HOME_ADDRESS);

  //Set Text Area
  writeData(_TA);
  writeData(0x00);
  writeCommand(T6963_SET_TEXT_AREA);

  //Set Internal CGRAM address
  writeData(((_sizeMem/2)-1));
  writeData(0x00);
  writeCommand(T6963_SET_OFFSET_REGISTER);


  setDispMode(true,true,false,false);

  setMode('O','I');

  clearText();
  clearGraphic();
  delay(100);

}

T6963.h

/*-------------------------------------------------------------------------------------------------
0.0- What these 2 guys built that I worked from
      Graphic LCD with Toshiba T6963 controller
      Copyright (c) Rados�aw Kwiecie�, 2007r
      http://en.radzio.dxp.pl/t6963/
      Compiler : avr-gcc
      Modified By -Gil- to work on Arduino easily : http://domoduino.tumblr.com/
0.1- Invocable class T6963
      Commands moved to T6963_commands.h
      For some reason I don't have reset hooked up and all is working fine.
0.2- rbrsidedn
      renamed SetPixel(byte,byte,byte) -> writePixel(x,y,color)
      added setPixel(x,y)
      added clearPixel(x,y)
      added createline(x1,y1,x2,y2)
      added createCircle(x,y,radius)       
r6 - Checked in with SVN
r7 - Checked in with cursor controls added
r8 - Got 6bit font width (s/b any fonth width) working.  
-----------------------------------------------------------------------------------------------*/
#ifndef T6963_h
#define T6963_h

#include "WProgram.h"
#include "inttypes.h"
#include "avr/io.h"
#include "avr/pgmspace.h"
#include "util/delay.h"
#include "T6963_Commands.h"

// data port
#define GLCD_DATA_PORT1 	PORTD
#define GLCD_DATA_PIN1		PIND
#define GLCD_DATA_DDR1		DDRD
#define GLCD_DATA_SHIFT1	<<2
#define GLCD_DATA_RSHIFT1	>>2
#define GLCD_DATA_MASK1		0xFC

#define GLCD_DATA_PORT2 	PORTB
#define GLCD_DATA_PIN2		PINB
#define GLCD_DATA_DDR2		DDRB
#define GLCD_DATA_SHIFT2	>>6
#define GLCD_DATA_RSHIFT2	<<6
#define GLCD_DATA_MASK2		0x03

// control port
#define GLCD_CTRL_PORT		PORTC
#define GLCD_CTRL_PIN		PINC
#define GLCD_CTRL_DDR		DDRC
// control signals
#define GLCD_WR				0
#define GLCD_RD				1
#define GLCD_CE				2  //Should be able to XNOR this with WR and RD
#define GLCD_CD				3
//#define GLCD_RESET			4  //For some reason my LCD works with this pin resistored to +5
//#define GLCD_FS				5  //Use hardware solution not pin.

// display properties

const byte T6963_CURSOR_PATTERN_SELECT=0xA0; //cursor patter select command prefix or with desired size-1.
const byte T6963_DISPLAY_MODE=0x90; 


class T6963{
public:
  T6963(int pixHoriz,int pixVert,int fontWidth, int sizeMem); //Class
  //pixHoriz = Horizontal resolution
  //pixVert = Vertical Resolution
  //fontWidth = pixel width of font, determines number of columns, use hardware setting for LCD, no outputs linked to this variable.
  //sizeMem = size of memory attached to LCD in kb s/b 4,8,16,32,64 type number.
  
  void InitalizeInterface(void);
  void writeCommand(byte);
  void writeData(byte);
  byte ReadData(void);
  void clearText(void);
  void clearCG(void);
  void clearGraphic(void);
  void WriteChar(char ch);
  void WriteString(char * str);
  void WriteStringPgm(prog_char * str);
  void TextGoTo(byte, byte);
  void GraphicGoTo(byte x, byte y);
  void DefineCharacter(unsigned char, unsigned char *);
  void Initialize(void);
  void writePixel(byte, byte, byte);
  byte clearPixel(byte,byte);
  byte setPixel(byte,byte);
  void WriteDisplayData(byte);
  byte checkStatus(void);
  void SetAddressPointer(unsigned int address);
  byte setMode(char, char);
  byte clearDispMode();
  byte setDispMode(boolean _text,boolean _graphics, boolean _cursor, boolean _blink);
  byte setCursorPattern(byte _b);
  byte setCursorPointer(byte _col,byte _row);
  
  void createLine(int,int,int,int);
  void createCircle(int, int, int);
  
  void setTH(unsigned int addr);
  unsigned int getTH();
  void setGH(unsigned int addr);
  unsigned int getGH();
  unsigned int sizeGA;	//(GLCD_GRAPHIC_AREA * GLCD_NUMBER_OF_LINES)
  unsigned int sizeTA;	//(GLCD_TEXT_AREA * (GLCD_NUMBER_OF_LINES/8))
  byte getTextRows();
  byte getTextCols();
   
private:
  void plot8points(int, int, int, int);
  void plot4points(int, int, int, int);
  unsigned int GLCD_NUMBER_OF_LINES;	//Veritical Resolution, Lines
  unsigned int GLCD_PIXELS_PER_LINE;	//Horizontal Resolution, pixels per line
  unsigned int _FW;		//Font Width
  unsigned int _GH;		//Graphics home
  unsigned int _TH;		//Text Home
  unsigned int _GA;		//(GLCD_PIXELS_PER_LINE / GLCD_FONT_WIDTH)
  unsigned int _TA;		//(GLCD_PIXELS_PER_LINE / GLCD_FONT_WIDTH)
  byte _sizeMem;  //memory location for CGRAM (2kb required, 64kb max memory controlled by T6963, 32 possible locations)

};


#endif

T6963_Commands.h

#include "WProgram.h"
#define T6963_SET_CURSOR_POINTER	0x21
#define T6963_SET_OFFSET_REGISTER	0x22
#define T6963_SET_ADDRESS_POINTER	0x24

#define T6963_SET_TEXT_HOME_ADDRESS	0x40
#define T6963_SET_TEXT_AREA		0x41
#define T6963_SET_GRAPHIC_HOME_ADDRESS	0x42
#define T6963_SET_GRAPHIC_AREA		0x43

#define T6963_MODE_SET                  0x80
			

#define T6963_SET_DATA_AUTO_WRITE	0xB0
#define T6963_SET_DATA_AUTO_READ	0xB1
#define T6963_AUTO_RESET		0xB2

#define T6963_DATA_WRITE_AND_INCREMENT	  0xC0
#define T6963_DATA_READ_AND_INCREMENT	  0xC1
#define T6963_DATA_WRITE_AND_DECREMENT	  0xC2
#define T6963_DATA_READ_AND_DECREMENT	  0xC3
#define T6963_DATA_WRITE_AND_NONVARIALBE  0xC4
#define T6963_DATA_READ_AND_NONVARIABLE	  0xC5

#define T6963_SCREEN_PEEK		0xE0
#define T6963_SCREEN_COPY		0xE8
24 Jan 2011

Looks very interesting. Once I can get to write to my display, I might use some of this stuff as well. I am using a Newhaven 5.7" TFT LCD with SSD1963 driver chip).