summaryrefslogtreecommitdiff
path: root/uisimulator/lcd-recorder.c
diff options
context:
space:
mode:
Diffstat (limited to 'uisimulator/lcd-recorder.c')
-rw-r--r--uisimulator/lcd-recorder.c174
1 files changed, 174 insertions, 0 deletions
diff --git a/uisimulator/lcd-recorder.c b/uisimulator/lcd-recorder.c
new file mode 100644
index 0000000000..37f4d3b142
--- /dev/null
+++ b/uisimulator/lcd-recorder.c
@@ -0,0 +1,174 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Daniel Stenberg <daniel@haxx.se>
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20/*
21 * Hardware-specific implementations for the Archos Recorder LCD.
22 *
23 * Archos Jukebox Recorder LCD functions.
24 * Solomon SSD1815Z controller and Shing Yih Technology G112064-30 LCD.
25 *
26 */
27
28/* LCD command codes */
29#define LCD_CNTL_RESET 0xe2 /* Software reset */
30#define LCD_CNTL_POWER 0x2f /* Power control */
31#define LCD_CNTL_CONTRAST 0x81 /* Contrast */
32#define LCD_CNTL_OUTSCAN 0xc8 /* Output scan direction */
33#define LCD_CNTL_SEGREMAP 0xa1 /* Segment remap */
34#define LCD_CNTL_DISPON 0xaf /* Display on */
35
36#define LCD_CNTL_PAGE 0xb0 /* Page address */
37#define LCD_CNTL_HIGHCOL 0x10 /* Upper column address */
38#define LCD_CNTL_LOWCOL 0x00 /* Lower column address */
39
40
41/*
42 * Initialize LCD
43 */
44void lcd_init (void)
45{
46 /* Initialize PB0-3 as output pins */
47 PBCR2 &= 0xff00; /* MD = 00 */
48 PBIOR |= 0x000f; /* IOR = 1 */
49
50 /* Initialize LCD */
51 lcd_write (TRUE, LCD_CNTL_RESET);
52 lcd_write (TRUE, LCD_CNTL_POWER);
53 lcd_write (TRUE, LCD_CNTL_SEGREMAP);
54 lcd_write (TRUE, LCD_CNTL_OUTSCAN);
55 lcd_write (TRUE, LCD_CNTL_CONTRAST);
56 lcd_write (TRUE, 0x30); /* contrast parameter */
57 lcd_write (TRUE, LCD_CNTL_DISPON);
58
59 lcd_clear();
60 lcd_update();
61}
62
63/*
64 * Update the display.
65 * This must be called after all other LCD funtions that change the display.
66 */
67void lcd_update (void)
68{
69 int row, col;
70
71 /* Copy display bitmap to hardware */
72 for (row = 0; row < DISP_Y/8; row++) {
73 lcd_write (TRUE, LCD_CNTL_PAGE | (row & 0xf));
74 lcd_write (TRUE, LCD_CNTL_HIGHCOL);
75 lcd_write (TRUE, LCD_CNTL_LOWCOL);
76
77 for (col = 0; col < DISP_X; col++)
78 lcd_write (FALSE, display[row][col]);
79 }
80}
81
82/*
83 * Display a string at current position
84 */
85void lcd_string (const char *text, BOOL invert)
86{
87 int ch;
88
89 while ((ch = *text++) != '\0') {
90 if (lcd_y > DISP_Y-CHAR_Y) {
91 /* Scroll (8 pixels) */
92 memcpy (display[0], display[1], DISP_X*(DISP_Y/8-1));
93 lcd_y -= 8;
94 }
95
96 if (ch == '\n')
97 lcd_x = DISP_X;
98 else {
99 lcd_char (ch, invert);
100 lcd_x += CHAR_X;
101 }
102
103 if (lcd_x > DISP_X-CHAR_X) {
104 /* Wrap to next line */
105 lcd_x = 0;
106 lcd_y += CHAR_Y;
107 }
108 }
109}
110
111/*
112 * Display a character.
113 * This writes a 5x8 character within a 6x8 cell.
114 * The cell does not have to be aligned to a display byte.
115 * The top left of the cell is displayed at the current position.
116 * invert is TRUE to display in reverse video.
117 */
118void lcd_char (int ch, BOOL invert)
119{
120 uchar (*dp)[DISP_X] = (void *) &display[lcd_y/8][lcd_x];
121 uint32 shift, mask, col;
122
123 /* Limit to char generation table */
124 if (ch < ASCII_MIN || ch > ASCII_MAX)
125 ch = ASCII_MAX;
126
127 /* Calculate shift and masks for cell bit position */
128 shift = (lcd_y & 0x7);
129 mask = ~(COL_MASK << shift);
130 if (invert)
131 invert = ~mask;
132
133 /* Write each char column */
134 for (col = 0; col < CHAR_X-1; col++) {
135 uint32 data = (char_gen[ch-ASCII_MIN][col] << shift) ^ invert;
136 dp[0][col] = (dp[0][col] & mask) | data;
137 if (lcd_y < DISP_Y-8)
138 dp[1][col] = (dp[1][col] & (mask >> 8)) | (data >> 8);
139 }
140
141 /* Column after char */
142 dp[0][CHAR_X-1] = (dp[0][CHAR_X-1] & mask) | invert;
143 if (lcd_y < DISP_Y-8)
144 dp[1][CHAR_X-1] = (dp[1][CHAR_X-1] & (mask >> 8)) | (invert >> 8);
145}
146
147/*
148 * Write a byte to LCD controller.
149 * command is TRUE if value is a command byte.
150 */
151static void lcd_write (BOOL command, int value)
152{
153 int i;
154
155 /* Read PBDR, clear LCD bits */
156 int pbdr = PBDR & ~(PBDR_LCD_CS1|PBDR_LCD_DC|PBDR_LCD_SDA|PBDR_LCD_SCK);
157 if (!command)
158 pbdr |= PBDR_LCD_DC; /* set data indicator */
159
160 /* Send each bit, starting with MSB */
161 for (i = 0; i < 8; i++) {
162 if (value & 0x80) {
163 /* Set data, toggle clock */
164 PBDR = pbdr | PBDR_LCD_SDA;
165 PBDR = pbdr | PBDR_LCD_SDA | PBDR_LCD_SCK;
166 }
167 else {
168 /* Clear data, toggle clock */
169 PBDR = pbdr;
170 PBDR = pbdr | PBDR_LCD_SCK;
171 }
172 value <<= 1;
173 }
174}