|
|
View previous topic :: View next topic |
Author |
Message |
amcfall
Joined: 20 Oct 2005 Posts: 44
|
Color LCD routines - Nokia 6100? / Epson S1D15G10 |
Posted: Wed Mar 22, 2006 5:43 pm |
|
|
This is for an LCD (128x128, 4096 colors) I bought from here:
http://www.sparkfun.com/commerce/product_info.php?products_id=569
I guess it's a Nokia clone, I don't know, I just bought a few because they were cheap. Here's some basic code for initialization and a pixel write function. I still need to experiment a little with the contrast and stuff, but on the 2 I have this code looks OK.
Code: |
//basic routines to drive an ERpson S1D15G00 series based LCD, like the ones from sparkfun.com
// Epson S1D15G10 Command Set and init sequence stolen from sparkfun.com example source code
#include <18F4620.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES BORV21 //Brownout reset at 2.1V
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
//#FUSES DEBUG
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES LPT1OSC //Timer1 configured for low-power operation
//#FUSES MCLR
#FUSES NOMCLR //Master Clear pin used for I/O
#use delay(clock=8000000)
#DEFINE _LCDPWR PIN_D1 //LCD defines
#DEFINE CS PIN_A5
#DEFINE LCDCLOCK PIN_C3
#DEFINE LCDDATA PIN_C5
#DEFINE _RESET PIN_C4
#DEFINE BLCONTROL PIN_D0
// Epson S1D15G10 Command Set
#define DISON 0xaf
#define DISOFF 0xae
#define DISNOR 0xa6
#define DISINV 0xa7
#define COMSCN 0xbb
#define DISCTL 0xca
#define SLPIN 0x95
#define SLPOUT 0x94
#define PASET 0x75
#define CASET 0x15
#define DATCTL 0xbc
#define RGBSET8 0xce
#define RAMWR 0x5c
#define RAMRD 0x5d
#define PTLIN 0xa8
#define PTLOUT 0xa9
#define RMWIN 0xe0
#define RMWOUT 0xee
#define ASCSET 0xaa
#define SCSTART 0xab
#define OSCON 0xd1
#define OSCOFF 0xd2
#define PWRCTR 0x20
#define VOLCTR 0x81
#define VOLUP 0xd6
#define VOLDOWN 0xd7
#define TMPGRD 0x82
#define EPCTIN 0xcd
#define EPCOUT 0xcc
#define EPMWR 0xfc
#define EPMRD 0xfd
#define EPSRRD1 0x7c
#define EPSRRD2 0x7d
#define NOP 0x25
void write_lcd(int1, unsigned int);
void init_lcd(int1);//0== 8 bit color, 1== send 16 bits (4096 color pallete)
void LCD_pixel_write8(unsigned int8, unsigned int8, unsigned int8);//8 bit color
void LCD_pixel_write16(unsigned int8, unsigned int8, unsigned int16);//takes a 16 bit color (RGB565) and shifts down to 12
void fill8(void);
void fill12(void);
void backlight_on(void);
void backlight_off(void);
void main()
{
unsigned int16 counter=0;
unsigned int x,y;
int8 eepromdata=123;
long int eepromaddress=0;
setup_wdt(WDT_OFF);
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_low_volt_detect(FALSE);
while(1)
{
init_lcd(0);
fill8();
delay_ms(2000);
init_lcd(1);
fill12();
delay_ms(2000);
}
}
void LCD_pixel_write8(unsigned int8 x, unsigned int8 y, unsigned int8 color)//8 bit color // x and y range 1-130 color 0-255 (RRRGGGBB)
{
if ((x > 130) | (x < 1) | (y > 130) | (y < 1))
return;
x=x+1;
y=y-1;
write_lcd(0, 0x75);//page start/end ram
write_lcd(1, x);
write_lcd(1, 131);
write_lcd(0, 0x15);//column start/end ram
write_lcd(1, y);
write_lcd(1, 129);
write_lcd(0, RAMWR);//RAM WRITE
write_lcd(1, color);
}
void LCD_pixel_write16(unsigned int8 x, unsigned int8 y, unsigned int16 color)// x and y range 1-128 color 16 bit (RRRRRGGGGGGBBBBB)
{
unsigned int8 colorhigh,colorlow,red,green,blue,data1,data2,data3;
if ((x > 130) | (x < 1) | (y > 130) | (y < 1))
return;
x=x+1;
y=y-1;
colorhigh=make8(color,1);//high byte
colorlow=make8(color,0);//low byte
red = (colorhigh >> 3);
green = ((colorhigh & 0b00000111) << 3) + ((colorlow & 0b11100000) >> 5);
blue = (colorlow & 0b00011111);
red=red>>1;//red was 5 bits, all now need to be 4
green=green>>2;//green was 6 bits
blue=blue>>1;
data1=((red<<4)+green);//send data:RRRRGGGG
data2=((blue<<4)+red);//BBBBRRRR
data3=((green<<4)+blue);//GGGGBBBB
write_lcd(0, 0x75);//page start/end ram
write_lcd(1, x);
write_lcd(1, 131);
write_lcd(0, 0x15);//column start/end ram
write_lcd(1, y);
write_lcd(1, 129);
write_lcd(0, RAMWR);//ram write
write_lcd(1, data1);
write_lcd(1, data2);
write_lcd(1, data3);
}
void fill12(void)
{
unsigned int16 i;
unsigned int8 x;
write_lcd(0, PASET);//page start/end ram
write_LCD(1, 2);//for some reason it starts at 2
write_LCD(1, 131);
write_lcd(0, CASET);//column start/end ram
write_LCD(1, 0);
write_LCD(1, 129);
write_lcd(0, RAMWR);//write a background
for (i=0; i< 16900; i++)
{
write_LCD(1, 0x0000);//black
write_LCD(1, 0x0000);
write_LCD(1, 0x0000);
}
for (x=1;x<=130;x++)//draw a border
{
lcd_pixel_write16(x,1,0xFBFF);
lcd_pixel_write16(x,130,0xFBFF);
lcd_pixel_write16(1,x,0xFBFF);
lcd_pixel_write16(130,x,0xFBFF);
}
}
void fill8(void)
{
unsigned int16 i;
unsigned int8 x;
write_lcd(0, PASET);//page start/end ram
write_LCD(1, 2);//for some reason it starts at 2
write_LCD(1, 131);
write_lcd(0, CASET);//column start/end ram
write_LCD(1, 0);
write_LCD(1, 129);
write_lcd(0, RAMWR);//write a background
for (i=0; i< 16900; i++)
write_LCD(1, 0x00); //black
for (x=1;x<=130;x++)//draw a border
{
lcd_pixel_write8(x,1,0xFF);
lcd_pixel_write8(x,130,0xFF);
lcd_pixel_write8(1,x,0xFF);
lcd_pixel_write8(130,x,0xFF);
}
}
void backlight_on(void)
{
output_high(blcontrol);
}
void backlight_off(void)
{
output_low(blcontrol);
}
|
Avery |
|
|
newby
Joined: 26 Sep 2004 Posts: 32
|
|
Posted: Sun Apr 09, 2006 2:28 am |
|
|
hi amcfall, great stuff !
It is indeed the display of the Nokia 6100.
I also have some of these displays but didnīt find the time to port available codes of other uCs by myself. Therefore i am very thankfull to find your work here !
But what about the contrast and the other stuff - did you solve these problems ? |
|
|
newby
Joined: 26 Sep 2004 Posts: 32
|
|
Posted: Tue Apr 11, 2006 6:35 am |
|
|
@amcfall:
unfortunately very important functions are missing in your code:
-> "init_lcd" and "write_lcd"
please post them also !!!!! |
|
|
amcfall
Joined: 20 Oct 2005 Posts: 44
|
|
Posted: Tue Apr 11, 2006 6:53 am |
|
|
newby wrote: | @amcfall:
unfortunately very important functions are missing in your code:
-> "init_lcd" and "write_lcd"
please post them also !!!!! |
DohH! I'll post that as soon as I remember.
I haven't done any more work, I'll have new boards here soon and I'll try different supply voltages and contrast settings then.
Avery |
|
|
Storic
Joined: 03 Dec 2005 Posts: 182 Location: Australia SA
|
|
|
newby
Joined: 26 Sep 2004 Posts: 32
|
|
Posted: Tue Apr 11, 2006 10:12 am |
|
|
@amcfall:
thanks a lot, we are waiting !!!!!!!
@Storic:
..you can find J1Mīs code also in this code library, but his glcd is only valid for the PHILIPS controller, not for the epson ! |
|
|
amcfall
Joined: 20 Oct 2005 Posts: 44
|
|
Posted: Thu Apr 13, 2006 3:19 pm |
|
|
Code: |
void write_lcd(int1 LCDmode, unsigned int data)//mode ==0 send a command, mode==1 sends data
{
if (!LCDmode)
output_low(LCDDATA);//when entering commands: SI=LOW at rising edge of 1st SCL
else
output_high(LCDDATA);//send data
output_low(LCDCLOCK);
output_high(LCDCLOCK);
//send data, 8th bit first
if (data & 128)
output_high(LCDDATA);
else
output_low(LCDDATA);
output_low(LCDCLOCK);
output_high(LCDCLOCK);
//7th bit
if (data & 64)
output_high(LCDDATA);
else
output_low(LCDDATA);
output_low(LCDCLOCK);
output_high(LCDCLOCK);
//6th bit
if (data & 32)
output_high(LCDDATA);
else
output_low(LCDDATA);
output_low(LCDCLOCK);
output_high(LCDCLOCK);
//5th bit
if (data & 16)
output_high(LCDDATA);
else
output_low(LCDDATA);
output_low(LCDCLOCK);
output_high(LCDCLOCK);
//4th bit
if (data & 8)
output_high(LCDDATA);
else
output_low(LCDDATA);
output_low(LCDCLOCK);
output_high(LCDCLOCK);
//3rd bit
if (data & 4)
output_high(LCDDATA);
else
output_low(LCDDATA);
output_low(LCDCLOCK);
output_high(LCDCLOCK);
//2nd bit
if (data & 2)
output_high(LCDDATA);
else
output_low(LCDDATA);
output_low(LCDCLOCK);
output_high(LCDCLOCK);
//1st bit
if (data & 1)
output_high(LCDDATA);
else
output_low(LCDDATA);
output_low(LCDCLOCK);
output_high(LCDCLOCK);
output_high(CS);
output_low(CS);
}
void init_lcd(int1 colormode)//colormode==0 8 bit
{//mode ==0 send a command, mode==1 sends data
unsigned int16 i;
unsigned int8 x,y;
output_low(_LCDPWR);//apply power to LCD
delay_ms(250);
output_low(CS);
output_low(LCDDATA);
output_high(LCDCLOCK);
output_high(_reset);
output_low(_reset);
output_high(_reset);
output_high(LCDCLOCK);
output_high(LCDDATA);
delay_ms(1);
write_lcd(0, DISCTL);//display control
write_LCD(1, 0x03);///original values
write_LCD(1, 0x20);
write_LCD(1, 0x0C);
write_LCD(1, 0x00);
write_lcd(0, NOP);//no op
write_lcd(0, COMSCN);//common scan direction
write_LCD(1, 0x01);
write_lcd(0, OSCON);//oscillator on
write_lcd(0, SLPOUT);//sleep out
write_lcd(0, VOLCTR);//electronic volume control
write_LCD(1, 0x05);//cares about lower 6 bits V1 volume
write_LCD(1, 0x01);//cares about lower 3 bits 1+Rb/Ra, supposed to specify "resistance ratio of internal resistor"
write_lcd(0, PWRCTR);//power control
write_LCD(1, 0x0f);//turn stuff on
write_LCD(1, 0x64);
write_lcd(0, DISINV);//inverse display
write_lcd(0, DATCTL);//Data control
write_LCD(1, 0x00);
write_LCD(1, 0x00);
// write_lcd(0, TMPGRD);//temp gradient
// write_LCD(1, 0);//
if (colormode == 0)//8 bit color
write_LCD(1, 0x01);
else
write_LCD(1, 0x02);//4096 colors
write_LCD(1, 0x00);
write_lcd(0, NOP);//no op
if (colormode == 0)//8 bit color
{
write_lcd(0, RGBSET8);//setup color lookup table
//red
write_LCD(1, 0);
write_LCD(1, 2);
write_LCD(1, 4);
write_LCD(1, 6);
write_LCD(1, 8);
write_LCD(1, 10);
write_LCD(1, 12);
write_LCD(1, 15);
//green
write_LCD(1, 0);
write_LCD(1, 2);
write_LCD(1, 4);
write_LCD(1, 6);
write_LCD(1, 8);
write_LCD(1, 10);
write_LCD(1, 12);
write_LCD(1, 15);
//blue
write_LCD(1, 0);
write_LCD(1, 4);
write_LCD(1, 9);
write_LCD(1, 15);
}
write_lcd(0, DISON);//display on
delay_ms(300);
write_lcd(0, NOP);//no op
for (i=0; i<150; i++)
{
write_lcd(0, VOLUP);//changes contrast, find correct setting by trial and error
}
}
|
If anyone gets a chance to experiment and finds better init values do let us know.
Avery |
|
|
newby
Joined: 26 Sep 2004 Posts: 32
|
|
Posted: Fri Apr 14, 2006 8:06 am |
|
|
i found a few minutes for a quick and dirty test and after some adaptions it works also on a 18F2620 and 18F2680 !!!
The color doesnīt seem to be "stable" that means it takes some time (0.5 - 1s) until the color reaches the final color, i guess this has something to do with the contrast and temperature settings ?!?
As soon as i have had time to play around with tht init, i wll let you know !
Thanks a lot amcfall ! |
|
|
amcfall
Joined: 20 Oct 2005 Posts: 44
|
|
Posted: Fri Apr 14, 2006 8:42 am |
|
|
One thing to mess around wioth is how many times you send VOLUP (the last thing we do in init_lcd). Unfortunately it's all trial and error. Originally I had a delay in that loop so you could judge the changes easier, but I guess I removed that.
Enjoy
Avery |
|
|
newby
Joined: 26 Sep 2004 Posts: 32
|
|
Posted: Sun Apr 16, 2006 8:32 am |
|
|
...this was a hard job !
Well, i spent about "1day" playing around with the VOLUP, but it didnīt change anything, there was no effect at all.
I tried a lot and finally my key issue was the DISCTL i had to change from your code
Code: | write_lcd(0, DISCTL);//display control
write_LCD(1, 0x03);///original values
write_LCD(1, 0x20);
write_LCD(1, 0x0C);
write_LCD(1, 0x00); |
to Code: | write_lcd(0, DISCTL);//display control
write_LCD(1, 0x0C);
write_LCD(1, 0x20);
write_LCD(1, 0x0C);
write_LCD(1, 0x00); |
itīs only the 1st line which sets the clock dividing ratio, in the 2nd line 0x1F also functions but you can see some stripes if you take a closer look under a slight angle
this seems to me to give the best quality, with the above settings i am able to set the contrast and the colors are also OK ! |
|
|
amcfall
Joined: 20 Oct 2005 Posts: 44
|
|
Posted: Tue Apr 18, 2006 9:48 am |
|
|
Great, as soon as my boards show up I'll try your modification. Out of curiousity, what kind of LCD do you have? I have the latest from Sparkfun, the one with the brown ribbon cable. I guess the green cables version has different settings even though both use the same Epson chip.
Avery |
|
|
newby
Joined: 26 Sep 2004 Posts: 32
|
|
Posted: Tue Apr 18, 2006 11:33 am |
|
|
I have "no idea" what type of LCD i have (i bought it at ebay), i only know that it is for the Nokia 6100 and has the green cables. Therefore i thought it has to be the epson controller - Bingo, the code works.
I also read in other forums that there is another epson controller around, the "S1D10605" which should be very rare and react similar to the philips - but still somehow different. I hope i donīt get one of these the next time i order. |
|
|
awelch
Joined: 03 Sep 2006 Posts: 2
|
|
Posted: Sun Sep 03, 2006 4:46 pm |
|
|
hey.. how did you guys wire up the sparkfun LCD to the PIC..?
you're using the 18 series chips? running at 3.3v? I want to hook it up to a 16F877 (it's all I have).. are the LCDs 5 volt signal tolerant?
thanks |
|
|
amcfall
Joined: 20 Oct 2005 Posts: 44
|
|
Posted: Tue Sep 05, 2006 6:03 am |
|
|
awelch wrote: | hey.. how did you guys wire up the sparkfun LCD to the PIC..?
you're using the 18 series chips? running at 3.3v? I want to hook it up to a 16F877 (it's all I have).. are the LCDs 5 volt signal tolerant?
thanks |
I made a custom board, although the Sparkfun breakout board would work also. No, the LCD is not 5V tolerant. I have used both 3.3v pics and a level shifter.
Avery |
|
|
awelch
Joined: 03 Sep 2006 Posts: 2
|
|
Posted: Tue Sep 05, 2006 7:56 am |
|
|
okay thanks..
That's what I thought and ordered some 74lvc125's to do the level shifting.. out of curiosity, which 3.3v pics did you use?
thanks again |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|