diff options
author | Dave Chapman <dave@dchapman.com> | 2006-02-05 16:01:50 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2006-02-05 16:01:50 +0000 |
commit | e8048cefed2715dcecb82ae49549ed619cf3104b (patch) | |
tree | 53b3bc65888735de5a1492b4b6a9c4e794d0c01d /firmware/drivers/lcd-ipod.c | |
parent | c6c584e4c1fcf46d058e23dc96c8dca8886466a8 (diff) | |
download | rockbox-e8048cefed2715dcecb82ae49549ed619cf3104b.tar.gz rockbox-e8048cefed2715dcecb82ae49549ed619cf3104b.zip |
Initial version of iPod greyscale LCD driver from Seven Le Mesle. This is currently written to use vertically-packed mono and native bitmap formats.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8580 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/lcd-ipod.c')
-rw-r--r-- | firmware/drivers/lcd-ipod.c | 201 |
1 files changed, 188 insertions, 13 deletions
diff --git a/firmware/drivers/lcd-ipod.c b/firmware/drivers/lcd-ipod.c index 0ff22ab9b5..2d165551e6 100644 --- a/firmware/drivers/lcd-ipod.c +++ b/firmware/drivers/lcd-ipod.c | |||
@@ -29,7 +29,192 @@ | |||
29 | #include "kernel.h" | 29 | #include "kernel.h" |
30 | #include "system.h" | 30 | #include "system.h" |
31 | 31 | ||
32 | /*** definitions ***/ | 32 | |
33 | /* check if number of useconds has past */ | ||
34 | static int timer_check(int clock_start, int usecs) | ||
35 | { | ||
36 | if ( ((int)(USEC_TIMER - clock_start)) >= usecs ) { | ||
37 | return 1; | ||
38 | } else { | ||
39 | return 0; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | |||
44 | #if (CONFIG_LCD == LCD_IPOD2BPP) | ||
45 | |||
46 | /*** hardware configuration ***/ | ||
47 | |||
48 | #define IPOD_LCD_BASE 0xc0001000 | ||
49 | #define IPOD_LCD_BUSY_MASK 0x80000000 | ||
50 | |||
51 | /* LCD command codes for HD66789R */ | ||
52 | |||
53 | |||
54 | #define LCD_CMD 0x08 | ||
55 | #define LCD_DATA 0x10 | ||
56 | |||
57 | static unsigned int lcd_contrast = 0x6a; | ||
58 | |||
59 | |||
60 | /* wait for LCD with timeout */ | ||
61 | static void lcd_wait_write(void) | ||
62 | { | ||
63 | int start = USEC_TIMER; | ||
64 | |||
65 | do { | ||
66 | if ((inl(IPOD_LCD_BASE) & 0x8000) == 0) break; | ||
67 | } while (timer_check(start, 1000) == 0); | ||
68 | } | ||
69 | |||
70 | |||
71 | /* send LCD data */ | ||
72 | static void lcd_send_data(int data_lo, int data_hi) | ||
73 | { | ||
74 | lcd_wait_write(); | ||
75 | outl(data_lo, IPOD_LCD_BASE + LCD_DATA); | ||
76 | lcd_wait_write(); | ||
77 | outl(data_hi, IPOD_LCD_BASE + LCD_DATA); | ||
78 | } | ||
79 | |||
80 | /* send LCD command */ | ||
81 | static void lcd_prepare_cmd(int cmd) | ||
82 | { | ||
83 | lcd_wait_write(); | ||
84 | |||
85 | outl(0x0, IPOD_LCD_BASE + LCD_CMD); | ||
86 | lcd_wait_write(); | ||
87 | outl(cmd, IPOD_LCD_BASE + LCD_CMD); | ||
88 | |||
89 | } | ||
90 | |||
91 | /* send LCD command and data */ | ||
92 | static void lcd_cmd_and_data(int cmd, int data_lo, int data_hi) | ||
93 | { | ||
94 | lcd_prepare_cmd(cmd); | ||
95 | |||
96 | lcd_send_data(data_lo, data_hi); | ||
97 | } | ||
98 | |||
99 | int lcd_default_contrast(void) | ||
100 | { | ||
101 | return 28; | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * | ||
106 | * LCD init | ||
107 | **/ | ||
108 | void lcd_init_device(void){ | ||
109 | /* driver output control - 160x128 */ | ||
110 | lcd_cmd_and_data(0x1, 0x1, 0xf); | ||
111 | lcd_cmd_and_data(0x5, 0x0, 0x10); | ||
112 | } | ||
113 | |||
114 | /*** update functions ***/ | ||
115 | /* srccopy bitblt, opcode is currently ignored*/ | ||
116 | |||
117 | /* Performance function that works with an external buffer | ||
118 | note that x and bwidtht are in 8-pixel units! */ | ||
119 | void lcd_blit(const unsigned char* data, int x, int by, int width, | ||
120 | int bheight, int stride) | ||
121 | { | ||
122 | /* TODO implement this on iPod */ | ||
123 | (void)data; | ||
124 | (void)x; | ||
125 | (void)by; | ||
126 | (void)width; | ||
127 | (void)bheight; | ||
128 | (void)stride; | ||
129 | } | ||
130 | |||
131 | /* Rolls up the lcd display by the specified amount of lines. | ||
132 | * Lines that are rolled out over the top of the screen are | ||
133 | * rolled in from the bottom again. This is a hardware | ||
134 | * remapping only and all operations on the lcd are affected. | ||
135 | * -> | ||
136 | * @param int lines - The number of lines that are rolled. | ||
137 | * The value must be 0 <= pixels < LCD_HEIGHT. */ | ||
138 | void lcd_roll(int lines) | ||
139 | { | ||
140 | /* TODO Implement lcd_roll() */ | ||
141 | lines &= LCD_HEIGHT-1; | ||
142 | } | ||
143 | |||
144 | /*** hardware configuration ***/ | ||
145 | |||
146 | /* Update the display. | ||
147 | This must be called after all other LCD functions that change the display. */ | ||
148 | void lcd_update(void) | ||
149 | { | ||
150 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); | ||
151 | } | ||
152 | |||
153 | void lcd_set_contrast(int val) | ||
154 | { | ||
155 | lcd_cmd_and_data(0x4, 0x4, val); | ||
156 | lcd_contrast = val; | ||
157 | } | ||
158 | |||
159 | void lcd_update_rect(int x, int y, int width, int height) | ||
160 | { | ||
161 | int cursor_pos, xx; | ||
162 | int ny; | ||
163 | int sx = x, sy = y, mx = width, my = height; | ||
164 | |||
165 | /* only update the ipod if we are writing to the screen */ | ||
166 | |||
167 | sx >>= 3; | ||
168 | //mx = (mx+7)>>3; | ||
169 | mx >>= 3; | ||
170 | |||
171 | cursor_pos = sx + (sy << 5); | ||
172 | |||
173 | for ( ny = sy; ny <= my; ny++ ) { | ||
174 | unsigned char * img_data; | ||
175 | |||
176 | |||
177 | // move the cursor | ||
178 | lcd_cmd_and_data(0x11, cursor_pos >> 8, cursor_pos & 0xff); | ||
179 | |||
180 | // setup for printing | ||
181 | lcd_prepare_cmd(0x12); | ||
182 | |||
183 | img_data = &lcd_framebuffer[ny][sx<<1]; | ||
184 | |||
185 | // 160/8 -> 20 == loops 20 times | ||
186 | // make sure we loop at least once | ||
187 | for ( xx = sx; xx <= mx; xx++ ) { | ||
188 | // display a character | ||
189 | lcd_send_data(*(img_data+1), *img_data); | ||
190 | |||
191 | img_data += 2; | ||
192 | } | ||
193 | |||
194 | // update cursor pos counter | ||
195 | cursor_pos += 0x20; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | /** Switch on or off the backlight **/ | ||
200 | void lcd_enable (bool on){ | ||
201 | int lcd_state; | ||
202 | |||
203 | lcd_state = inl(IPOD_LCD_BASE); | ||
204 | if (on){ | ||
205 | lcd_state = lcd_state | 0x2; | ||
206 | outl(lcd_state, IPOD_LCD_BASE); | ||
207 | lcd_cmd_and_data(0x7, 0x0, 0x11); | ||
208 | } | ||
209 | else { | ||
210 | lcd_state = lcd_state & ~0x2; | ||
211 | outl(lcd_state, IPOD_LCD_BASE); | ||
212 | lcd_cmd_and_data(0x7, 0x0, 0x9); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | #else | ||
217 | |||
33 | #define IPOD_LCD_BASE 0x70008a0c | 218 | #define IPOD_LCD_BASE 0x70008a0c |
34 | #define IPOD_LCD_BUSY_MASK 0x80000000 | 219 | #define IPOD_LCD_BUSY_MASK 0x80000000 |
35 | 220 | ||
@@ -42,17 +227,6 @@ | |||
42 | /*** globals ***/ | 227 | /*** globals ***/ |
43 | static int lcd_type = 1; /* 0 = "old" Color/Photo, 1 = "new" Color & Nano */ | 228 | static int lcd_type = 1; /* 0 = "old" Color/Photo, 1 = "new" Color & Nano */ |
44 | 229 | ||
45 | |||
46 | /* check if number of useconds has past */ | ||
47 | static inline int timer_check(unsigned long clock_start, unsigned long usecs) | ||
48 | { | ||
49 | if ( (USEC_TIMER - clock_start) >= usecs ) { | ||
50 | return 1; | ||
51 | } else { | ||
52 | return 0; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | static void lcd_wait_write(void) | 230 | static void lcd_wait_write(void) |
57 | { | 231 | { |
58 | if ((inl(IPOD_LCD_BASE) & IPOD_LCD_BUSY_MASK) != 0) { | 232 | if ((inl(IPOD_LCD_BASE) & IPOD_LCD_BUSY_MASK) != 0) { |
@@ -229,7 +403,7 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
229 | 403 | ||
230 | /* start vert = max vert */ | 404 | /* start vert = max vert */ |
231 | #if CONFIG_LCD == LCD_IPODCOLOR | 405 | #if CONFIG_LCD == LCD_IPODCOLOR |
232 | x0 = x1; | 406 | x0 = x1; |
233 | #endif | 407 | #endif |
234 | 408 | ||
235 | /* position cursor (set AD0-AD15) */ | 409 | /* position cursor (set AD0-AD15) */ |
@@ -288,3 +462,4 @@ void lcd_update(void) | |||
288 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); | 462 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); |
289 | } | 463 | } |
290 | 464 | ||
465 | #endif | ||