SparkFun Forums 

Where electronics enthusiasts find answers.

Your source for all things Atmel.
By Senso
#115266
About one month ago I bought one of this babies:
http://www.sparkfun.com/products/8799
Its really big and its stunningly beautiful.
I'm using one arduino, but only as a "programmer board" because all my development is done under WinAvr, the avr is one atmega328p.
From the code provided by sparkfun(in the huge VU meter tutorial) and in this site:
http://en.radzio.dxp.pl/t6963/
I made a driver(in fact I just copy/pasted almost the code from the above given link), and I cant get the lcd to display anything that makes sense, I only get one full screen of random on/off pixels, if I reset the pattern is the same(it never changes, even if I unplug the power from the lcd and the micro), if I change my string in the code the pattern changes, but I cant get to display anything that is correct, my code is this:
Code: Select all
#ifndef _BIGLCD_H_
#define _BIGLCD_H_

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/pgmspace.h>

//Data port
#define DATA_PORT	PORTD
#define DATA_PIN	PIND
#define DATA_DDR	DDRD

//Control port
#define CONTROL_PORT	PORTB
#define CONTROL_PIN		PINB
#define CONTROL_DDR		DDRB

//Control signals
#define WR	PB0		// /WR write
#define RD	PB1		// /RD read
#define CE	PB2		// /CE chip enable
#define CD	PB3		// /CD command/data
#define RST	PB4		// /RST reset

//Display size
#define LINES		128
#define COLLUMS		160
#define FONT_WIDTH	8
#define GRAPHIC_AREA	(COLLUMS / FONT_WIDTH)
#define TEXT_AREA		(COLLUMS / FONT_WIDTH)
#define GRAPHIC_SIZE	(GRAPHIC_AREA * LINES)
#define TEXT_SIZE		(TEXT_AREA * (LINES/8))

#define TEXT_HOME			0
#define GRAPHIC_HOME		(TEXT_HOME + TEXT_SIZE)
#define OFFSET_REGISTER		32
#define EXTERNAL_CG_HOME	((OFFSET_REGISTER/2)-1)

#define SET_CURSOR_POINTER	0x21
#define SET_OFFSET_REGISTER	0x22
#define SET_ADDRESS_POINTER	0x24

#define SET_TEXT_HOME_ADDRESS		0x40
#define SET_TEXT_AREA				0x41
#define SET_GRAPHIC_HOME_ADDRESS	0x42
#define SET_GRAPHIC_AREA			0x43

#define MODE_SET_OR				0x80
#define MODE_SET_EXOR			0x81
#define MODE_SET_AND			0x83
#define MODE_SET_TEXT_ATTRIBUTE	0x84
#define MODE_SET_CGROM			0x80
#define MODE_SET_CGRAM			0x88

#define DISPLAY_MODE		0x90
#define CURSOR_BLINK_ON		0x01
#define CURSOR_DISPLAY_ON	0x02
#define TEXT_DISPLAY_ON		0x04
#define GRAPHIC_DISPLAY_ON	0x08

#define CURSOR_PATERN_SELECT	0xA0
#define CURSOR_1_LINE			0x00
#define CURSOR_2_LINE			0x01
#define CURSOR_3_LINE			0x02
#define CURSOR_4_LINE			0x03
#define CURSOR_5_LINE			0x04
#define CURSOR_6_LINE			0x05
#define CURSOR_7_LINE			0x06
#define CURSOR_8_LINE			0x07

#define SET_DATA_AUTO_WRITE		0xB0
#define SET_DATA_AUTO_READ		0xB1
#define AUTO_RESET				0xB2

#define DATA_WRITE_AND_INCREMENT	0xC0
#define DATA_READ_AND_INCREMENT		0xC1
#define DATA_WRITE_AND_DECREMENT	0xC2
#define DATA_READ_AND_DECREMENT		0xC3
#define DATA_WRITE_AND_NONVARIABLE	0xC4
#define DATA_READ_AND_NONVARIABLE	0xC5

#define SCREEN_PEEK		0xE0
#define SCREEN_COPY		0xE8

#define WHITE	0x01
#define BLACK	0x00

void lcdPortConfig(void);
uint8_t CheckStatus(void);
void WriteCommand(uint8_t command);
void WriteData(uint8_t data);
void SetAddressPointer(uint16_t address);
void ClearText(void);
void ClearCG(void);
void ClearGraphic(void);
void WriteChar(char charCode);
void WriteString(char *string);
void WriteStringPGM(prog_char *string);
void TextXY(uint8_t x, uint8_t y);
void DefineChar(uint8_t charCode, char *defChar);
void SetPixel(uint8_t x, uint8_t y, uint8_t color);
void WriteDisplayData(uint8_t data);
void GraphicXY(uint8_t x, uint8_t y);
void Bitmap(uint8_t *bitmap, uint8_t x, uint8_t y, uint8_t width, uint8_t height);
void lcdInitialize(void);
void Rectangle(uint8_t x, uint8_t y, uint8_t xend, uint8_t yend);
void Circle(uint8_t cx, uint8_t cy, uint8_t radius);
void Line(int X1, int Y1,int X2,int Y2);

#endif

Code: Select all
#include "biglcd.h"

void lcdPortConfig(void){

DATA_DDR = 0xFF;	//Output
CONTROL_DDR = ((1<<WR)|(1<<RD)|(1<<CE)|(1<<CD)|(1<<RST));
CONTROL_PORT = ((1<<WR)|(1<<RD)|(1<<CE)|(1<<CD)|(1<<RST));
}

uint8_t CheckStatus(void){

uint8_t temp;
DATA_DDR = 0x00;	//Input to be able to read the status bits
CONTROL_PORT &= ~((1<<RD)|(1<<CE));
_delay_loop_1(10);	//Delay of 4*3 CPU cycles
temp = DATA_PIN;
DATA_DDR = 0xFF;	//Turn the data port again to output
CONTROL_PORT |= ((1<<RD)|(1<<CE));
return temp;
}

void WriteCommand(uint8_t command){

while(!(CheckStatus() & 0x03));		//Check if is possible to write a command
DATA_PORT = command;
CONTROL_PORT &= ~((1<<WR)|(1<<CE));
_delay_loop_1(10);
CONTROL_PORT |= ((1<<WR)|(1<<CE));
}

void WriteData(uint8_t data){

while(!(CheckStatus() & 0x03));	//Check if is possible to write data
DATA_PORT = data;
CONTROL_PORT &= ~((1<<WR)|(1<<CE)|(1<<CD));
_delay_loop_1(10);
CONTROL_PORT |= ((1<<WR)|(1<<CE)|(1<<CD));
}

uint8_t ReadData(void){

uint8_t temp;
while(!(CheckStatus() & 0x03));
DATA_DDR = 0x00;	//Going to read, so need to be input
CONTROL_PORT &= ~((1<<RD)|(1<<CE)|(1<<CD));
_delay_loop_1(10);
temp = DATA_PIN;
CONTROL_PORT |= ((1<<RD)|(1<<CE)|(1<<CD));
DATA_DDR = 0xFF;	//Back to output
return temp;
}


void SetAddressPointer(uint16_t address){

WriteData(address & 0xFF);
WriteData((address >> 8) & 0xFF);
WriteCommand(SET_ADDRESS_POINTER);
}

void ClearText(void){

int i;
SetAddressPointer(TEXT_HOME);

for(i=0; i<TEXT_SIZE; i++){
	WriteDisplayData(0);
	}
}

void ClearCG(void){

uint16_t i;
SetAddressPointer(EXTERNAL_CG_HOME);

for(i=0; i<256 * 8; i++){
	WriteDisplayData(0);
	}
}

void ClearGraphic(void){

int i;
SetAddressPointer(GRAPHIC_HOME);
for(i=0; i<GRAPHIC_SIZE; i++){
	WriteDisplayData(0x00);
	}
}

void WriteChar(char charCode){

WriteDisplayData(charCode-32);	//Due the built-in CG-ROM
}

void WriteString(char *string){

while(*string){
	WriteChar(*string++);
	}
}

void WriteStringPGM(prog_char *string){

char charCode;
while((charCode=pgm_read_byte(string++))){
	WriteChar(charCode);
	}
}


void TextXY(uint8_t x, uint8_t y){

uint16_t address;

address = TEXT_HOME + x + (TEXT_AREA * y);
SetAddressPointer(address);
}


void DefineChar(uint8_t charCode, char *defChar){

uint16_t address;
uint8_t i;

address = EXTERNAL_CG_HOME + (8*charCode);
SetAddressPointer(address);

for(i=0; i<8; i++){
	WriteDisplayData(*(defChar+i));
	}
}

void SetPixel(uint8_t x, uint8_t y, uint8_t color){

uint8_t temp;
uint16_t address;

address = GRAPHIC_HOME + (x/FONT_WIDTH) + (GRAPHIC_AREA * y);
SetAddressPointer(address);
WriteCommand(DATA_READ_AND_NONVARIABLE);
temp = ReadData();

if(color){
	temp |= (1<< (FONT_WIDTH - 1 - (x % FONT_WIDTH))); }
else{
	temp &= ~((1<< (FONT_WIDTH - 1 - (x % FONT_WIDTH)))); }

WriteDisplayData(temp);
}

void WriteDisplayData(uint8_t data){

WriteData(data);
WriteCommand(DATA_WRITE_AND_INCREMENT);
}

void GraphicXY(uint8_t x, uint8_t y){

uint16_t address;
address = GRAPHIC_HOME + (x / FONT_WIDTH) + (GRAPHIC_AREA * y);
SetAddressPointer(address);
}


void Bitmap(uint8_t *bitmap, uint8_t x, uint8_t y, uint8_t width, uint8_t height){

uint8_t i, j;

for(j=0; j<height; j++){
	GraphicXY(x,y+j);
	for(i=0; i<width/FONT_WIDTH;i++){
		WriteDisplayData(pgm_read_byte(bitmap + i + (GRAPHIC_AREA * j)));
		}
	}
}

void lcdInitialize(void){

lcdPortConfig();
CONTROL_PORT &= ~(1<<RST);
_delay_ms(1);
CONTROL_PORT |= (1<<RST);

WriteData(GRAPHIC_HOME & 0xFF);
WriteData((GRAPHIC_HOME >> 8) & 0xFF);
WriteCommand(SET_GRAPHIC_HOME_ADDRESS);

WriteData(GRAPHIC_AREA);
WriteData(0x00);
WriteCommand(SET_GRAPHIC_AREA);

WriteData(TEXT_HOME & 0xFF);
WriteData((TEXT_HOME >> 8) & 0xFF);
WriteCommand(SET_TEXT_HOME_ADDRESS);

WriteData(TEXT_AREA);
WriteData(0x00);
WriteCommand(SET_TEXT_AREA);

WriteData(OFFSET_REGISTER);
WriteData(0x00);
WriteCommand(SET_OFFSET_REGISTER);

WriteCommand(DISPLAY_MODE | GRAPHIC_DISPLAY_ON | TEXT_DISPLAY_ON);
WriteCommand(MODE_SET_OR);
}

void Rectangle(uint8_t x, uint8_t y, uint8_t xend, uint8_t yend){

uint8_t i;
for(i=0; i<yend; i++){
	SetPixel(x, y+i, WHITE);
	SetPixel(x+xend-1, y+i, WHITE);
	}

for(i=0; i<xend; i++){
	SetPixel(x+i, y, WHITE);
	SetPixel(x+i, y+yend-1, WHITE);
	}
}

void Circle(uint8_t cx, uint8_t cy, uint8_t radius){

int x, y, xchange, ychange, radiusError;
x=radius;
y=0;
xchange=1-2*radius;
ychange=1;
radiusError=0;

while(x>=y){
	SetPixel(cx+x, cy+y, WHITE);
	SetPixel(cx-x, cy+y, WHITE);
	SetPixel(cx-x, cy-y, WHITE);
	SetPixel(cx+x, cy-y, WHITE);
	SetPixel(cx+y, cy+x, WHITE);
	SetPixel(cx-y, cy+x, WHITE);
	SetPixel(cx-y, cy-x, WHITE);
	SetPixel(cx+y, cy-x, WHITE);
	y++;
	radiusError += ychange;
	ychange +=2;
	if((2*radiusError + xchange) > 0){
		x--;
		radiusError += xchange;
		xchange += 2;
		}
	}
}

void Line(int X1, int Y1,int X2,int Y2){
int CurrentX, CurrentY, Xinc, Yinc, 
    Dx, Dy, TwoDx, TwoDy, 
	TwoDxAccumulatedError, TwoDyAccumulatedError;

Dx = (X2-X1);
Dy = (Y2-Y1);

TwoDx = Dx + Dx;
TwoDy = Dy + Dy;

CurrentX = X1;
CurrentY = Y1;

Xinc = 1;
Yinc = 1;

if(Dx < 0){
  Xinc = -1;
  Dx = -Dx;
  TwoDx = -TwoDx;
  }

if (Dy < 0){
  Yinc = -1;
  Dy = -Dy;
  TwoDy = -TwoDy;
  }

SetPixel(X1,Y1, WHITE);

if ((Dx != 0) || (Dy != 0)){

  if (Dy <= Dx){ 
    TwoDxAccumulatedError = 0;
    do{
      CurrentX += Xinc;
      TwoDxAccumulatedError += TwoDy;
      if(TwoDxAccumulatedError > Dx){
        CurrentY += Yinc;
        TwoDxAccumulatedError -= TwoDx;
        }
       SetPixel(CurrentX,CurrentY, WHITE);
       }while (CurrentX != X2);
     }
   else {
      TwoDyAccumulatedError = 0; 
      do{
        CurrentY += Yinc; 
        TwoDyAccumulatedError += TwoDx;
        if(TwoDyAccumulatedError>Dy) {
          CurrentX += Xinc;
          TwoDyAccumulatedError -= TwoDy;
          }
         SetPixel(CurrentX,CurrentY, WHITE); 
         }while (CurrentY != Y2);
    }
  }
}
And finally the main:
Code: Select all
#include <avr/io.h>
#include "biglcd.h"

int main(void){

lcdInitialize();
ClearText();
ClearCG();
ClearGraphic();

//TextXY(5,5);
//WriteString("Work!!! :(");

//Circle(2,2,20);

while(1);
return 1;
}
Even with only the init and clear routines the lcd keeps displaying one random pattern, the only difference that I see from my init sequence is well, the strange way of calculating the external CG RAM home that I cant understand and the values used in the init sequence about where are located each text and graphic area, this is the init code from sparkfun:
Code: Select all
void display_init(void)
{
	//set graphics home address to 0
	while(!(read(0) & 3));//read status
	write(1, 0);
	while(!(read(0) & 3));//read status
	write(1, 0);
	while(!(read(0) & 3));//read status
	write(0, 0x42);

	//set graphics area
	while(!(read(0) & 3));//read status
	write(1, 20);//20 bytes, 160/8
	while(!(read(0) & 3));//read status
	write(1, 0);
	while(!(read(0) & 3));//read status
	write(0, 0x43);
	
	//set mode
	while(!(read(0) & 3));//read status
	write(0, 0x80);//Or, with internal character generator
	
	//set display mode
	while(!(read(0) & 3));//read status
	write(0, 0x98);//Graphics on

}
Sorry for the lengthy post, but this forum doesn't support spoiler bars to hide the code, and also thanks in advance to everyone that read my post.