[s1mp3-dev] HOWTO: figure out your LCD/OLED display
Alistair Buxton
a.j.buxton at gmail.com
Thu Jun 22 08:09:01 CDT 2006
Okay, some people have been having trouble getting the loadram samples to
display anything on their screen. I've been investigating, and this is what
I found:
I had one player that worked perfectly and one that would only draw in a
thin band (actually it turns out this is a page.)
I looked in to the programming method for LCD displays, and learned they
have two modes: data mode, where you write the raw data to the screen, and
command mode, where you do things like position the cursor. The mode is
controlled by a GPIO line which must be turned on or off. Since we know that
manufacturers like to rewire the GPIO different in every player, I guessed
that this was the cause of the problem.
The first thing i found while playing around is that writing to any address
0x8000-0xFFFF ends up at the LCD data input. So it looks like the ATJ's CE3
line (also known as "LCD enable" in some docs) is wired directly to the
internal address bus highest bit.
So I disassembled every file in my player's firmware ( for i in `ls`; do
echo $i; z80dasm $i > $i.asm; done) and looked for writes (ld) to any
address above 0x8000 (inclusive.) (Using grep, of course.) Obviously there
were a lot. From looking at the examples I noticed that 0x8000 and 0x8001 is
normally used for accessing the LCD, so I narrowed the search to these
addresses. Only a few firmware modules actually had these addresses, most
notable the files UI_xxxx.DRV.
I looked more closely at the UI_L0724.DRV disassembly (L=latin?), and found
this:
push bc ; 000805 C5
in a,($f4) ; 000806 DB F4
and $fb ; 000808 E6 FB
out ($f4),a ; 00080A D3 F4
ld a,c ; 00080C 79
ld ($8000),a ; 00080D 32 00 80
pop bc ; 000810 C1
ret ; 000811 C9
in a,($f4) ; 000812 DB F4
or $04 ; 000814 F6 04
out ($f4),a ; 000816 D3 F4
ld a,(hl) ; 000818 7E
ld ($8001),a ; 000819 32 01 80
inc hl ; 00081C 23
djnz $0818 ; 00081D 10 F9
ret ; 00081F C9
These are clearly subroutines!
The first subroutine turns off a GPIO line, and the second turns one on...
just what we are looking for. Also, they both write to the LCD. The second
one writes the data from (hl) to (hl+b) so it looks like a routine to copy
graphics to the LCD. The first one only ever writes one byte, so it looks
like it's passing a command. It seems like a convention to use 0x8000 when
sending a command, and 0x8001 when sending data, although these addresses
are interchangable.
After googling for 8080 lcd programming commands for a while, I found this
PDF with some LCD commands:
http://serdisplib.sourceforge.net/ser/doc/sed1560.pdf
Sure enough, once I had the correct port and bit, these commands worked on
my display, at least the simple ones did.
BTW the display I was using is not actually LCD, but mono OLED. I just used
the term "LCD" cos I'm too lazy to type "display." I'm 99% certain all
display types will use exactly the same commands - although the pixels will
be packed differently on colour displays - you will still see something,
even if it looks like garbage...
I hope this is of some help to the people who were asking about LCD
programming in the IRC. Hopefully others will be able to follow my steps and
discover the gpio mapping of their display, and then we can get more people
coding :)
--
Alistair Buxton
a.j.buxton at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://s1mp3.org/pipermail/s1mp3-dev_s1mp3.org/attachments/20060622/1a997179/attachment.htm
More information about the s1mp3-dev
mailing list