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:
#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
#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:
#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:
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.