Skip to content

Commit 25c9775

Browse files
committed
starting point for LCD info
1 parent 4023f85 commit 25c9775

21 files changed

Lines changed: 573 additions & 4 deletions

File tree

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ This is the repo for the Pokémon mini documentation hosted [here](https://www.p
4848
- Interrupts
4949
- Oscillators & Timers
5050
- I/O ports & protocols ?
51-
- LCD Driver / PRC
51+
- LCD Controller / PRC
5252
- Statuses (SLEEP/HALT)
53-
- LCD: SED1565* (display driver)
53+
- LCD: S1D15605* (display driver)
5454
- on this page:
5555
- Tech specs
5656
- dimensions
@@ -171,6 +171,5 @@ This is the repo for the Pokémon mini documentation hosted [here](https://www.p
171171
- Find the main loop
172172
- Understanding the RAM locations (and using BPs)
173173
- Using the debug output system
174-
- Challenge: that CTF someone made, with spoilers
175174
- .minc format ?
176175

hardware/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The machine has a 4 KiB internal mask ROM (BIOS), 4 KiB of internal RAM (shared
1515
- [Audio / Sound](cpu/Sound.md)
1616
- [LCD Controller](cpu/LCD_Controller.md)
1717
- [Standby modes](cpu/Standby.md)
18-
- [LCD: SED15xx](LCD.md)
18+
- [LCD: S1D15xxx](LCD.md)
1919
- [EEPROM: 24xx64 alike](EEPROM.md)
2020
- [IR Transceiver](IR.md)
2121
- [Piezo Speaker](Speaker.md)

hardware/lcd/README.md

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# LCD and LCD Driver
2+
3+
## LCD screen
4+
5+
* Dimensions:
6+
* Glass: 35mm x 32mm\* x 2mm
7+
* \* ~7mm of the top is for the driver chip and FPC connection and otherwise "empty" glass
8+
* Display area: approx. 28mm x 19.5mm
9+
* Reflector panel: approx. 34.8mm x 24.7mm
10+
* Pixels: 96 x 64
11+
* Markings on glass (display side):
12+
* Upper left: `A` centered over `F11`
13+
* Upper right: `7680`
14+
* A `+` on either side
15+
* Dots around where the FPC connects with lines above them that match to etched lines on the FPC
16+
* Marking on FPC: `1012-90`
17+
18+
Taped to the plastic front with clear, double-sided 3 mm wide tape in a hollow rectangle shape, the rectangle being approx. 35.4mm x 27.6mm on the outside
19+
20+
The reflector is taped to the board with approx. 28mm (l) x 4mm (w) x 3.6mm (h) black foam tape
21+
22+
## S1D15xxx LCD driver
23+
24+
[S1D15000 Series Technical Manual](https://www.crystalfontz.com/controllers/uploaded/Epson%20S1D15605_SED1565_577706%20Tech%20Manual%20v1.1.pdf)
25+
26+
* Part number: S1D15605?xxxx??
27+
* S1 - Seiko Epson, previously SE
28+
* D - Model name: Driver
29+
* 15605 - Model number
30+
* ? - Shape (unknown)
31+
* xxxx - Specifications (unknown)
32+
* ?? - Packing specification (unknown)
33+
* Supply voltage range: 1.8 to 5.5 V
34+
* LCD voltage range: 4.5 to 16 V
35+
* Duty: 1/65 (1/7, 1/9 bias)
36+
* Segments: 132
37+
* Commons: 65
38+
* Display RAM: 132x65 = 8580 bits
39+
* Microprocessor interface: 8-bit parallel
40+
* Frequency: 33 KHz
41+
* Package: Chip on Glass (COG)
42+
* Built-in power circuit for LCD (DC/DCx4)
43+
44+
The driver runs in parallel mode (P/S = HIGH), master operation (M/S = HIGH), with the internal oscillator circuit disabled (C/S = LOW). Thus the CL line takes input from the MCU via OSC1 and the FR line switching resets register $8A to 1 and increases $81's frame counter by 1 (see page 8-29 for a diagram).
45+
46+
### Commands
47+
48+
To simplify interaction with the LCD, try [libpmdd](https://github.com/logicplace/libpmdd) instead of direct access.
49+
50+
LCD_CTRL is primarily used for sending commands to the LCD driver and is accessible through register $FE on the PM.
51+
52+
LCD_DATA is primarily used for sending display data to the LCD driver and is accessible through register $FF on the PM.
53+
54+
LCD_CTRL and LCD_DATA both write and read over the D0-D7 lines, it determines what operation is happening and whether CTRL or DATA is being read/written by the status of the A0, <u style="text-decoration:overline">RD</u>, & <u style="text-decoration:overline">WR</u> lines.
55+
56+
| A0 | <u style="text-decoration:overline">RD</u> | <u style="text-decoration:overline">WR</u> | R/W | CTRL/DATA |
57+
|---|---|---| ----- | ---- |
58+
| 0 | 0 | 1 | Read | CTRL |
59+
| 0 | 1 | 0 | Write | CTRL |
60+
| 1 | 0 | 1 | Read | DATA |
61+
| 1 | 1 | 0 | Write | DATA |
62+
63+
#### Command list
64+
65+
Listed below are the commands, written to CTRL.
66+
67+
| Cmd # | Command | Command Code | Hex range |
68+
|----------:| ------------------ | --------------- | --------- |
69+
| [1][] | Display ON/OFF | 1 0 1 0 1 1 1 x | $AE - $AF |
70+
| [2][] | Display start line | 0 1 a a a a a a | $40 - $7F |
71+
| [3][] | Set Page | 1 0 1 1 a a a a | $B0 - $BF |
72+
| [4a][4] | Set Column HI | 0 0 0 1 h h h h | $10 - $1F |
73+
| [4b][4] | Set Column LO | 0 0 0 0 l l l l | $00 - $0F |
74+
| [8][] | ADC select | 1 0 1 0 0 0 0 x | $A0 - $A1 |
75+
| [9][] | Invert | 1 0 1 0 0 1 1 x | $A6 - $A7 |
76+
| [10][] | All on | 1 0 1 0 0 1 0 x | $A4 - $A5 |
77+
| [11][] | LCD bias | 1 0 1 0 0 0 1 x | $A2 - $A3 |
78+
| [12][] | Start RMW | 1 1 1 0 0 0 0 0 | $E0 |
79+
| [13][12] | End RMW | 1 1 1 0 1 1 1 0 | $EE |
80+
| [14][] | Reset | 1 1 1 0 0 0 1 0 | $E2 |
81+
| [15][] | Row direction | 1 1 0 0 x - - - | $C0 - $CF |
82+
| [16][] | Power control | 0 0 1 0 1 m m m | $28 - $2F |
83+
| [17][] | V5 resistor ratio | 0 0 1 0 0 r r r | $20 - $27 |
84+
| [18a][18] | Contrast | 1 0 0 0 0 0 0 1 | $81 |
85+
| [18b][18] | Contrast | - - v v v v v v | $00 - $FF |
86+
| [19a][19] | Static indicator | 1 0 1 0 1 1 0 x | $AC - $AD |
87+
| [19b][19] | Static indicator | - - - - - - m m | $00 - $FF |
88+
| [20][] | Power saver | | |
89+
| [21][] | NOP | 1 1 1 0 0 0 1 1 | $E3 |
90+
| [22][] | Test | 1 1 1 1 - - - - | $F0 - $FF |
91+
92+
[1]: cmd/1.md
93+
[2]: cmd/2.md
94+
[3]: cmd/3.md
95+
[4]: cmd/4.md
96+
[5]: cmd/5.md
97+
[6]: cmd/6.md
98+
[7]: cmd/7.md
99+
[8]: cmd/8.md
100+
[9]: cmd/9.md
101+
[10]: cmd/10.md
102+
[11]: cmd/11.md
103+
[12]: cmd/12.md
104+
[14]: cmd/14.md
105+
[15]: cmd/15.md
106+
[16]: cmd/16.md
107+
[17]: cmd/17.md
108+
[18]: cmd/18.md
109+
[19]: cmd/19.md
110+
[20]: cmd/20.md
111+
[21]: cmd/21.md
112+
[22]: cmd/22.md
113+
114+
#### Writing to display RAM
115+
116+
Writes the byte to display RAM at the current cursor location then increments the cursor by 1. When the cursor reaches the end of the current page, it *does not* wrap around to the next page, you must do this manually.
117+
118+
The data sent is displayed in a column of the current page formed as 0bABCDEFGH being (when rows are...)
119+
120+
| Normal | Reversed |
121+
|:------:|:--------:|
122+
| H | A |
123+
| G | B |
124+
| F | C |
125+
| E | D |
126+
| D | E |
127+
| C | F |
128+
| B | G |
129+
| A | H |
130+
131+
Then moves one column to the right (if ADC is normal) or left (if ADC is reversed).
132+
133+
#### Reading display RAM
134+
135+
TODO: how to read reliably
136+
137+
Reading from LCD_DATA reads the byte in display RAM where the cursor is currently. If the driver is currently operating in RMW mode, the cursor is not incremented after reading. Otherwise, it is incremented.
138+
139+
TODO: does ADC reverse reading direction?
140+
141+
#### Reading display status
142+
143+
Read from LCD_CTRL. TODO: how to read reliably
144+
145+
The returned byte contains status information in the upper nibble:
146+
147+
* D7 - BUSY - 1 = busy, 0 = not busy
148+
* "Busy" means doing some sort of internal process or reset, during which it cannot accept commands.
149+
* There's no need to check the busy signal.
150+
* D6 - ADC - 0 = reverse, 1 = normal
151+
* This is opposite to the assignment command.
152+
* The command $A0 will cause this status bit to be 1.
153+
* The command $A1 will cause this status bit to be 0.
154+
* D5 - ON/OFF - 0 = ON 1 = OFF
155+
* This is opposite to the assignment command.
156+
* The command $AE will cause this status bit to be 0.
157+
* The command $AF will cause this status bit to be 1.
158+
* D4 - RESET - 1 = reset in progress
159+
160+
## FPC board connector pinout
161+
162+
TODO: orientation
163+
164+
1. VRS
165+
2. V5
166+
3. V4
167+
4. V3
168+
5. V2
169+
6. V1
170+
7. CAP2-
171+
8. CAP2+
172+
9. CAP1-
173+
10. CAP1+
174+
11. CAP3- (mislabled as CAP3+ in the block diagram)
175+
12. VOUT
176+
13. VSS (GND)
177+
14. VDD (VCC)
178+
15. D7
179+
16. D6
180+
17. D5
181+
18. D4
182+
19. D3
183+
20. D2
184+
21. D1
185+
22. D0
186+
23. <u style="text-decoration:overline">RD</u>
187+
24. <u style="text-decoration:overline">WR</u>
188+
25. A0
189+
26. <u style="text-decoration:overline">RES</u>
190+
27. CS
191+
28. CL
192+
29. FR

hardware/lcd/cmd/1.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Display ON/OFF
2+
3+
* To turn the display on, use:
4+
* libpmdd: `LCD_PWR(ON);`
5+
* C raw: `LCD_CTRL = 0xAF;`
6+
* ASM: `LD LCD_CTRL, #0AFh`
7+
* To turn the display off, use:
8+
* libpmdd: `LCD_PWR(OFF);`
9+
* C raw: `LCD_CTRL = 0xAE;`
10+
* ASM: `LD LCD_CTRL, #0AEh`
11+
* To turn the display on properly, use:
12+
* C: `_int(0x56);`
13+
* ASM: `INT [56h]`
14+
* To turn the display off properly, use:
15+
* C: `_int(0x5A);`
16+
* ASM: `INT [5Ah]`
17+
18+
Note that sending [display all points](10.md) on ($A5) while the display is off, the display will enter [power saving mode](20.md).
19+
20+
TODO: what is the power savings for turning the LCD off? without power savings mode

hardware/lcd/cmd/10.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Display all points
2+
3+
* To render normally, use:
4+
* libpmdd: `LCD_SETALL(OFF);`
5+
* C raw: `LCD_CTRL = 0xA4;`
6+
* ASM: `LD LCD_CTRL, #0A4h`
7+
* To render all pixels as on, use:
8+
* libpmdd: `LCD_SETALL(ON);`
9+
* C raw: `LCD_CTRL = 0xA5;`
10+
* ASM: `LD LCD_CTRL, #0A5h`
11+
12+
This does not alter the contents of the display RAM.
13+
14+
You can use this to create flashing effects. Combine with [invert](9.md) to flash white instead of black (TODO: confirm).
15+
16+
If the display is off, sending setall on ($A5) will enable [power saving mode](20.md).
17+
18+
When in standby mode, sending setall off ($A4) will cancel it. When in sleep mode, you must also send [static indicator on](19.md) to cancel it.

hardware/lcd/cmd/11.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# LCD bias set
2+
3+
Don't mess with this as it could possibly damage the LCD.
4+
5+
* To use 1/9 voltage bias, use:
6+
* libpmdd: `LCD_VBIAS(NORMAL);`
7+
* C raw: `LCD_CTRL = 0xA2;`
8+
* ASM: `LD LCD_CTRL, #0A2h`
9+
* To to use 1/7 voltage bias, use:
10+
* libpmdd: `LCD_VBIAS(DARK);`
11+
* C raw: `LCD_CTRL = 0xA3;`
12+
* ASM: `LD LCD_CTRL, #0A3h`
13+
14+
Set to normal in the BIOS during LCD initialization [here](../../../software/bios/disasm/#user-content-089C).

hardware/lcd/cmd/12.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Read/Modify/Write
2+
3+
* To start RMW mode, use:
4+
* libpmdd: `LCD_RMW(ON);`
5+
* C raw: `LCD_CTRL = 0xE0;`
6+
* ASM: `LD LCD_CTRL, #0E0h`
7+
* To stop RMW mode, use the end command via:
8+
* libpmdd: `LCD_RMW(OFF);`
9+
* C raw: `LCD_CTRL = 0xEE;`
10+
* ASM: `LD LCD_CTRL, #0EEh`
11+
12+
This mode causes the cursor to not increment when reading the display data. Conceptually, this could be used to blit new pixels atop the existing screen.
13+
14+
When the end command is sent, the cursor returns to where it was when RMW began. Conceptually, this could be used to more quickly modify a section of the screen for an animation, such as a blinking cursor or decimal seconds digits on a clock.
15+
16+
Because reading requires a dummy read, it may be appropriate to use this mode in order to read a single byte from the LCD without moving the cursor. If you intend to read multiple sequential bytes, though, you can do without it.

hardware/lcd/cmd/14.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Reset
2+
3+
* To reset the display/driver:
4+
* libpmdd: `LCD_RESET();`
5+
* C raw: `LCD_CTRL = 0xE2;`
6+
* ASM: `LD LCD_CTRL, #0E2h`
7+
8+
This resets all settings to the default state. It's essentially equivalent to running these in order:
9+
10+
* `LCD_RMW(OFF)` - releases the read/modify/write mode
11+
* `LCD_STATIC(0)` - resets the static indicator: (D1, D2) = (0, 0)
12+
* `LCD_SHIFT(0)` - initializes the display start line
13+
* `LCD_COL(0)` - resets the column address
14+
* `LCD_PAGE(0)` - resets the page address
15+
* `LCD_ROW(NORMAL)` - resets the common output mode
16+
* resets the V5 voltage regulator internal resistor ratio
17+
* default unknown
18+
* `LCD_CONTRAST(32)` - resets the electronic volume
19+
* `LCD_NOP()` - releases the test mode
20+
21+

hardware/lcd/cmd/15.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Common output mode select
2+
3+
* To display rows top to bottom, use:
4+
* libpmdd: `LCD_ROW(NORMAL);`
5+
* C raw: `LCD_CTRL = 0xC0;`
6+
* ASM: `LD LCD_CTRL, #0C0h`
7+
* To display rows bottom to top, use:
8+
* libpmdd: `LCD_ROW(REVERSE);`
9+
* C raw: `LCD_CTRL = 0xC8;`
10+
* ASM: `LD LCD_CTRL, #0C8h`
11+
12+
The normal display for rows is:
13+
14+
```
15+
Row 0
16+
Row 1
17+
...
18+
Row 62
19+
Row 63
20+
```
21+
22+
But when `LCD_ROW(REVERSE);` is used then the rows are displayed as:
23+
24+
```
25+
Row 63
26+
Row 62
27+
...
28+
Row 1
29+
Row 0
30+
```
31+
32+
When combining row reverse with [changing the starting row](2.md), it shifts up instead, so that `LCD_SHIFT(1);` causes row 0 to be on top, followed by row 63. (TODO: confirm)

hardware/lcd/cmd/16.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Power controller set
2+
3+
Don't mess with this as it could possibly damage the LCD.
4+
5+
* To change the power supply configuration, use:
6+
* libpmdd: `LCD_PWR_CTL(x);`
7+
* C raw: `LCD_CTRL = 0x28 | x;`
8+
* ASM: `LD LCD_CTRL, #028h | x`
9+
10+
In the above, x stores three bit flags 0bBVF:
11+
12+
* B = Booster circuit
13+
* V = Voltage regulator circuit
14+
* F = Voltage follower (V/F) circuit
15+
16+
The docs provide the following table on page 8-32 and warn that other combinations are not recommended:
17+
18+
| Use Settings | D2 | D1 | D0 | B | V | F | External voltage input | Step-up voltage system terminal |
19+
| Only the internal power supply is used | 1 | 1 | 1 | O | O | O | VSS2 | Used |
20+
| Only the V regulator circuit and the V/F circuit are used | 0 | 1 | 1 | X | O | O | VOUT, VSS2 | Open |
21+
| Only the V/F circuit is used | 0 | 0 | 1 | X | X | O | V5, VSS2 | Open |
22+
| Only the external power supply is used | 0 | 0 | 0 | X | X | X | V1 to V5 | Open |
23+
24+
In the BIOS, this is set to 0b111 when the [LCD is initialized](../../../software/bios/disasm/#user-content-08A4) and to 0b000 when the [LCD is turned off](../../../software/bios/disasm/#user-content-08E2).
25+
26+
It's very possible that the other modes do nothing or may damage the console. (TODO: real messaging)

0 commit comments

Comments
 (0)