Binary and source (v182.zip) can be found in the SAM7 file gallery.Release notes are here.
The board was bought here.
The bare displays can also be found here. The site (sparkfun) also has variations of this display along with other types such as OLED.
One pain with these displays is they don't all have the same (built in) controllers. There are at least two types and the controllers may also be clones themselves. The two known types are (or based on) philips and epson controllers. These are also know as type 12 and 8 (eg ge-12).
The two controllers have different instructions so you have to have the right software for the particular device. Some programs claim to handle both but have very limited features.
Most of the ground work has already been done by James P. Lynch, Loren Blaney, Owen Osborn and others.
I started out porting the code from this tutorial (by James P. Lynch) which is for the Philips type.
There is no obvious way to tell which controller is present (a test program would have been useful).
You can sometimes tell by the sticker on the new display but this was long gone.
Later I learned the connector colour is a clue - green for epson brown for philips.
I vaguely remembered it being a type-8 but wasn't sure. I ultimately wrote code for both types.
I had many bugs and stupidity errors in my code and after working through them all I confirmed that is is an epson controller. According to the WWW it is a S1D15G10D08B000 - a datasheet can be found here.
Compared to the alternatives it is fairly cheap (US$15) has acceptable display quality and a very simple hardware interface interface (SPI).
They are very basic graphical displays. They do not accept high level commands found in more advanced displays. They do not contain a character generator.
You basically write raw data to a user defined window into the display ram. There are no commands set a pen colour, draw a line, box, arc or characters - all these things must be done in user software.
The windowing does aid in drawing lines, boxes and characters. Drawing single points is inefficient.
There is no access to individual bits planes - changing N pixels means sending a minimum of N bytes plus a setup overhead.
With my current configuration a complete screen fill in 12 bit mode takes 79 milliseconds so it quite fast enough for me.
The cheapness and simple interface also makes it practical to use multiple displays if one isn't enough.
An 8 bit AVR micro would have enough grunt to drive this display but I like using FORTH and I want fair bit of RAM for storing an hour or two of data.
One defect in the SAM7EX256 design is there is no SPI data line back to the SAM7 from the display. This doesn't matter too much in this case but should I ever want to write a more general purpose GUI I would want to read portions (clips) of the display which are going to be overwritten so I can restore the clip regions. I've had this problem before and had to keep multiple copies of the display data in main RAM to get around it.
The other reason to want to read from the display is to detect which controller is fitted and act accordingly.
Mr Lynch seems to think having the origin in the lower left is correct and seemed puzzled that that wasn't the default setting. I've found having a top left origin almost universal but I don't get out much.
Top left is the standard windows way and is what I'm used to from programming in delphi. It is also the default for C# (but changeable?) and common programs such as irfanview.
A top left origin seems natural in some ways - we read from top left for example. One time it is unnatural is when drawing graphs which tend the use "positive for up" axis system.
I think I will go for a top origin but I'm not certain yet.
I have problem. I haven't been able to get single pixel writes to work properly in 12 bit mode. Someone has gone before me and apparently got it working - here. Unfortunately this doesn't seem to be working for me.
Changing the DATCTL parameter 3 to from 2 to 4 doesn't seem to make any difference.
Maybe I have an old controller? I may have done something stupid but the code is pretty simple and I've spent a lot of time trying to sort it out.
I just checked and the I've had the ex256 since Aug-2007 or earlier so it may have been an early version on the controller.
I don't actually want to use 12 bit mode so I may just move on to 8-bit.
Hmmm, another dragon or new instance of same dragon. I can't enter 8-bit mode. DATCTL parameter 3 doesn't seem to work for me. DATCTL parameter 2 works and I can change the RGB order on the fly with it.
These problems usually end up being a software bug but I'm running out of things to try and I'm seriously thinking of trying to swap out this display for a new one (which I haven't ordered yet).
Google is my friend...
Apparently there is an Epson (S1D15G00) controller out there which does not do the "two bytes one pixel" format but it *should* still do 8-bit.
Also some chips don't like the NOP commands used in some drivers.
What a mess. It seems my bug really could be hardware (insert Marg Simpson growl).
This must be causing some head-ache for nokia phone spare parts people too.
I can live without 8-bit mode if I have to. Even the single pixel write are only an issue if I want to draw graphs (which I do). I can draw single pixels now but the colours are wrong. I could work around it.
The real problem is any new displays I buy could end up being anything. I could buy three or four and find they are all different. Those OLEDs are looking better all the time.
|The LCD is stuck on with poster tape and lifted quite easily to uncouple the plug from socket. Once the display is lifted - there is the possibility of adding a wire to bring the other SPI line back to the micro.|
|The mirror for the back light is flexible plastic and did get a few kinks from being removed. These were not obvious when the display was closed up again.|
|The two LEDs are very bright. It is surprising that such a simple leds+mirror works as well as it does. I'm assuming the LEDs need 7V because they are in series. I see a potential hack here to run on a 5V system without voltage boosting.|
|Here is the outside (front and back) of the open display showing the folded out ribbon and serial number.|
So replacement looks quite doable. I guess I'll order a display or two.
Here's a sample of the commands. They are being interpreted here but could be complied.
NLCLR ." The quick brown fox" LCDCR ." jumped over the laxy" LCDCRPRECLR // yes I know it should be "lazy" ." FORTH programmer." LCDCRPSTCLR RED SETPENCOL ." Some red text." LCDCRPRECLR YELLOW SETBGCOL ." now on yellow" LCDCRPRECLR
The 12 bit format makes character generation a pain. You send three bytes to define two pixels so there is some bit shifting needed to make it all work. To make it a little easier my inner loop processes two bits at a time so this code only works for characters with an even width (six in this case).
HEX : CHAR>LCD // CHAR -- MT; 20 - FONTH * FONT6x8 + // convert to table element address // set up the display ram window. CURSY @ DUP // get curser Y, dup it PASET LCDCMD // send command LCDDATA FONTH + 1- LCDDATA // send y then y + char width-1 CURSX @ DUP // get curser x, dup it CASET LCDCMD // send command LCDDATA FONTW + 1- LCDDATA // send x then x + char height-1 // now write the pixels into the ram RAMWR LCDCMD // send memory write command FONTH 0 DO // do once for each row DUP C@ // get the byte for the chargen table. FONTW 2/ 0 DO // do this for width/2 DUP TSTMASK AND IF // test the high bit of our shifter. PENCOLOUR // set so member pen colour variable address ELSE BGCOLOUR // clear so member back colour variable address THEN @ C LSHIFT >R // get the 12 bits of colour and shift up 12 bit, save it to R 2* // move shifter left one bit. DUP // process this bit the same way as before. TSTMASK AND IF PENCOLOUR ELSE BGCOLOUR THEN @ R> + // get colour data for the second bit and merge with the first DUP 10 RSHIFT LCDDATA // write the three bytes [two pixels] of data to ram DUP 8 RSHIFT LCDDATA LCDDATA 2* // shift left LOOP // repeat till row done. DROP // drop the shifted value 1+ // inc the chargen pointer to next byte -ie next row LOOP // repeat till char done. DROP // drop chargen pointer CHARW CURSX +! // move cursor to next char position - done. NB may remove this ; // because we may want to write down the screen as well as across
|This is the sort of thing I had in mind. This is just a demo - I don't have any real data to display yet. The user should be able to see at a glance if there are any problems because I can use colours to highlight bad things.|
It behaves just like the old one - 8-bit mode does not work and mode-4 (2 bytes/pixel) does not work. I was really beginning to doubt my programming abilities until google led me to the comment below which is on the spark-fun LCD page (already linked above). This is quite a recent comment and it seems he found the same problem. I also have the blue cast he mentions. It seems other people have found some other weirdness.
This is a copy of Ian's (hackaday) comment. If you are using this display it is worth going to the sparkfun page here and clicking the comment button at the bottom of the page.
ian at hackaday.com's rank:
+1.3 | February 23, 2009 at 6:46 AM
+0.32 The new batch (red tab, green connector PCB, white potting, winter 2008/9) has some non-minor differences with the previous EPSON LCDs. It works with the current SFE code. I noted these differences:
- The newer LCD doesn't support the DATCTL color mode (byte 3) 0x01 (8bit) or 0x04 (12bit/pixel, 2bytes per pixel). It does support the 12bits/2pixels/3byte mode (0x02).
- The newer LCD does not seem to respond to the column/page settings (flip and rotate) in DACTL byte 1, bits 0-2.
- The newer LCD needs a higher/greater contrast value to eliminate the off-blue hue. 35 on the old screen is 40-45 on the new one.
- The newer LCD seems to generally be lower-quality than the previous ones I've ordered from SFE. I get horizontal banding in the image that may be due to a missed setting, but it's good enough to live with.
- I couldn't find a 'common ground' configuration that works with both models. I had to compile custom firmware for each version.
It seems like I can write single pixels reliably if I send not two but three data bytes.
This is my DOT routine for setting a single pixel.
: DOT // Y,X,Colour - MT; >R PASET LCDCMD DUP LCDDATA LCDDATA CASET LCDCMD DUP LCDDATA LCDDATA R> RAMWR LCDCMD DUP LCDDATA DUP 8 RSHIFT LCDDATA LCDDATA ;
The above code sends GGGGBBBB 0000RRRR GGGGBBBB and this seemed a little strange.
It turns out
0 LCDDATA DUP 8 RSHIFT LCDDATA LCDDATAalso works.
So it seems the first byte is ignored and we can send 00000000 0000RRRR GGGGBBBB
I've tested most common colours on black,white and grey backgrounds and see nothing amiss.
There seem to be a number of affordable OLED displays around. These are a bit over twice the price of the LCD but being Aussie delivery should be cheaper for me. The SSD1339 controller seems to be used on quite a few types so hopefully we won't have the same controller mess again - I can hope.
Like the LCD controllers above these OLED controllers can be configured for either parallel or SPI. Being LEDs there is no need for a back-light. More reading to do but so far they look good.