S1D13700 Graphic LCD Timing Shenanigans

The S1D13700 is an LCD controller IC made by Epson. It is common among 320×240 monochrome LCDs. It has a software interface that is similar or identical to the SED1335 and Raio RA8835. Recently, I had the pleasure of writing some software for it. Several quirks made it kind of a pain, so I thought I share for the next guy.

First, have a look at the timing diagram found in the S1D13700 Datasheet.

S1D13700 Datasheet Timing

S1D13700 Datasheet Timing

OK, now stop looking at it because it’s wrong. For some reason, following that timing pattern produces unstable results when writing to the graphics layer. Here is a video demonstrating the type of problems you end up with:

It turns out the trick is to only activate the CS line while you transition the WR or RD pin on its sensitive edge but not the other edge. So, when writing, you would only hold CS low long enough to transition WR from high to low. The opposite applies to RD. Here are some working code snippets:

void GLCD_WriteCommand(unsigned char commandToWrite)
{

SED1335_DATA_PORT = commandToWrite;
SED1335_DATA_DIR = 0;
SED1335_CONTROL_PORT &= ~(SED1335_WR);
SED1335_CONTROL_PORT &= ~SED1335_CS;
SED1335_CONTROL_PORT |= (SED1335_WR);
SED1335_CONTROL_PORT |= SED1335_CS;
}

and

unsigned char GLCD_ReadData(void)
{
unsigned char tmp;
SED1335_CONTROL_PORT &= ~(SED1335_CS);
SED1335_DATA_DIR = 0xFF;
SED1335_CONTROL_PORT &= ~(SED1335_RD);
READDELAY();
tmp =  SED1335_DATA_PIN;
SED1335_CONTROL_PORT |= (SED1335_CS);
SED1335_CONTROL_PORT |= (SED1335_RD);
return tmp;
}

Since that did not cause enough frustration and productivity loss, there is another gotcha. There is an apparently vital but unmentioned (I couldn’t find it in the datasheet) delay that must be inserted after the initial system set command and before the parameters are passed for that command. If you don’t ensure a proper delay, the LCD either won’t start or, strangely, will output the wrong data when you attempt to do a read. So the start of  the initialization routine should look something like this:

GLCD_HardReset();

GLCD_WriteCommand(SED1335_SYSTEM_SET);
_delay_us(500);
GLCD_WriteData(SED1335_SYS_P1);
GLCD_WriteData(SED1335_SYS_P2);  
GLCD_WriteData(SED1335_FY);
GLCD_WriteData(SED1335_CR);
GLCD_WriteData(SED1335_TCR);
GLCD_WriteData(SED1335_LF);
GLCD_WriteData(SED1335_APL);
GLCD_WriteData(SED1335_APH);

I hope that helps someone struggling with this controller.

The full code examples can be found here

    • Dave Stowe
    • August 10th, 2011

    Hi !
    I recently purchased this screen from you on Ebay.
    I am happy with it, got the touch screen working well and a calibration routine done for it no problems. It is when I started doing drawings on the screen I found a problem.
    Its doing something weird. Every now and again the screen seems to lock up whilst drawing lines. It does not matter where on the screen I draw the line, and its very random when it does it! It looks like it starts to do the line, as you can see where it stopped when I reset. The Arduino is still running as I have used the led on pin 13 pulsed every second.

    Any ideas?

    Many Regards

    Dave Stowe

  1. 8DVRAN zfipawtwvmpd

  2. 4Sc71i rtclseqyvuje

    • James
    • February 19th, 2012

    Hi!

    I have a problem with 320×240 Yamaha MM6 display, would it help if I apply thicker wires?

    • colonel
    • May 4th, 2012

    hi,

    Thank you so much for your article, i’m going to the same problem, started once (crystal ok) but now not anymore
    i’m looking for timing too…
    Trying to understand the datasheet is a real headache…

  1. No trackbacks yet.