// Routines to draw pixels in 4096 colors on the Nokia LCD
// with the Epson S1D15G10 "compatible" controller.
// by Loren Blaney, 26-Oct-2007
// Based on code by James Lynch.
// Epson S1D15G10 LCD controller command list
#define DISON 0xAF // Display on
#define DISOFF 0xAE // Display off
#define DISNOR 0xA6 // Normal display
#define DISINV 0xA7 // Inverse display
#define COMSCN 0xBB // Common scan direction
#define DISCTL 0xCA // Display control
#define SLPIN 0x95 // Sleep in
#define SLPOUT 0x94 // Sleep out
#define PASET 0x75 // Page address set
#define CASET 0x15 // Column address set
#define DATCTL 0xBC // Data scan direction, etc.
#define RGBSET8 0xCE // 256-color position set
#define RAMWR 0x5C // Writing to memory
#define RAMRD 0x5D // Reading from memory
#define PTLIN 0xA8 // Partial display in
#define PTLOUT 0xA9 // Partial display out
#define RMWIN 0xE0 // Read and modify write
#define RMWOUT 0xEE // End
#define ASCSET 0xAA // Area scroll set
#define SCSTART 0xAB // Scroll start set
#define OSCON 0xD1 // Internal oscillation on
#define OSCOFF 0xD2 // Internal oscillation off
#define PWRCTR 0x20 // Power control
#define VOLCTR 0x81 // Electronic volume control
#define VOLUP 0xD6 // Increment electronic control by 1
#define VOLDOWN 0xD7 // Decrement electronic control by 1
#define TMPGRD 0x82 // Temperature gradient set
#define EPCTIN 0xCD // Control EEPROM
#define EPCOUT 0xCC // Cancel EEPROM control
#define EPMWR 0xFC // Write into EEPROM
#define EPMRD 0xFD // Read from EEPROM
#define EPSRRD1 0x7C // Read register 1
#define EPSRRD2 0x7D // Read register 2
#define NOP 0x25 // NOP instruction
void drawPixel(int x, int y, int color) {
// Draw a pixel at the specified coordinates and color
// x = column address [0..129]
// y = row address [0..129]
// color = 16-bit color value: 0000_RRRR_GGGG_BBBB
x+=2; // visible display starts in column 2
spiCmd(CASET); // set column address
spiData(x); // start
spiData(x); // end
spiCmd(PASET); // set page (row) address
spiData(y); // start
spiData(y); // end
spiCmd(RAMWR);
spiData(color>>8); // big endian style
spiData(color);
} // drawPixel
void fillWin(int area, int color) { // Fill window with specified color
int i;
spiCmd(RAMWR);
for (i=0; i>8); // big endian: 0000_RRRR_GGGG_BBBB
spiData(color);
}
} // fillWin
int setWin(int x0, int y0, int x1, int y1) {
// Set rectangular area for a window on the LCD
// Returns its area (in pixels)
int t;
if (x0>x1) {t=x0; x0=x1; x1=t;} // put coordinates into ascending order
if (y0>y1) {t=y0; y0=y1; y1=t;}
spiCmd(CASET); // set column address
spiData(x0+2); // start (visible area starts in column 2)
spiData(x1+2); // end
spiCmd(PASET); // set page (row) address
spiData(y0); // start
spiData(y1); // end
return (x1-x0+1) * (y1-y0+1); // area
} // setWin
int penX, penY; // pen coordinates
#define fontHeight 8 // character height in pixels = number of bytes
void chOut(char ch) { // Draw ASCII character at penX,penY
int i, j, c, byte;
setWin(penX, penY, penX+7, penY+fontHeight-1);
spiCmd(RAMWR);
ch -= 0x20; // table starts with the space character
for (j=0; j>8);
spiData(c);
byte = byte << 1;
}
}
penX += 8; // move to next character position
} //chOut
void initLcd(void) { // Initialize the Epson S1D15G00 LCD controller
TRISB = 0xFF13; //outputs: dat=7 clk=6 spk=5 cs=3 rst=2
asm volatile ("nop");
LATB = 0xf00C; // dat(7)=0 clk(6)=0 spk(5)=0 cs(3)=1 rst(2)=1
asm volatile ("nop");
PORTB = 0xf00C;
RPOR3 = 0x0708; // set SPI on RB7=SDO1(07); RB6=SCLK1OUT(08)
SPI1CON1 = 0x013F;
SPI1CON2 = 0x0000;
SPI1STAT = 0x8000;
LCD_RESET = 0; // reset the controller
delayMS(10);
LCD_RESET = 1;
delayMS(10);
LCD_CS = 0; // enable the chip
spiCmd(DISCTL); // Display control
spiData(0); // 2 divisions, switching period=8 (default)
spiData(32); // nlines/4 - 1 = 132/4 - 1 = 32)
spiData(0); // no inversely highlighted lines
spiCmd(COMSCN); // Common scan directions
spiData(1); // Scan 1->80, 160<-81
spiCmd(OSCON); // turn on internal oscillator
spiCmd(SLPOUT); // Sleep out
spiCmd(PWRCTR); // Power control
spiData(0x0F); // everything on: reference voltage, regulator,
// circuit voltage follower, and boosters
spiCmd(DISINV); // Inverse display (for proper colors)
spiCmd(DATCTL); // Data control
spiData(0x03); // page address inverted, column address normal,
// address scan in page direction
spiData(0x00); // RGB sequence (default)
==> spiData(0x04); // special mode selects 12-bit color for single pixels <==
spiCmd(VOLCTR); // Voltage control
spiData(33); // contrast setting: 0..63
spiData(3); // resistance ratio (only value that works)
fillWin(setWin(0, 0, 131, 131), 0); // clear display memory
delayMS(100); // wait for power supply voltage to stabilize
spiCmd(DISON); // turn on the display
} // initLcd