summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2008-10-25 23:22:02 +0000
committerDave Chapman <dave@dchapman.com>2008-10-25 23:22:02 +0000
commit34535494a7402529a465c36245ecf12f7369d91f (patch)
treeceb01f1da2e81346d8b59895e8047fa497d7a52c /firmware/target/arm
parent2fb63ae6a8c32ffff751b1745e746dab015d1704 (diff)
downloadrockbox-34535494a7402529a465c36245ecf12f7369d91f.tar.gz
rockbox-34535494a7402529a465c36245ecf12f7369d91f.zip
A little more work on the e200v2 LCD driver (still untested - I don't own one). The lcd_update*() functions are taken from the X5 LCD driver.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18881 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c152
1 files changed, 99 insertions, 53 deletions
diff --git a/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c b/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c
index e14ad21681..1ffd9fddd5 100644
--- a/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c
+++ b/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c
@@ -34,7 +34,7 @@
34 34
35static bool display_on = false; /* is the display turned on? */ 35static bool display_on = false; /* is the display turned on? */
36static bool display_flipped = false; 36static bool display_flipped = false;
37static int xoffset = 0; /* needed for flip */ 37static int y_offset = 0; /* needed for flip */
38 38
39/* register defines */ 39/* register defines */
40#define R_START_OSC 0x00 40#define R_START_OSC 0x00
@@ -79,23 +79,22 @@ static int xoffset = 0; /* needed for flip */
79#define R_HORIZ_RAM_ADDR_POS 0x44 79#define R_HORIZ_RAM_ADDR_POS 0x44
80#define R_VERT_RAM_ADDR_POS 0x45 80#define R_VERT_RAM_ADDR_POS 0x45
81 81
82#define LCD_CMD (*(volatile unsigned short *)0xf0000000)
83#define LCD_DATA (*(volatile unsigned short *)0xf0000002)
84
85#define R_ENTRY_MODE_HORZ 0x7030 82#define R_ENTRY_MODE_HORZ 0x7030
86#define R_ENTRY_MODE_VERT 0x7038 83#define R_ENTRY_MODE_VERT 0x7038
84#define R_ENTRY_MODE_SOLID_VERT 0x1038
87 85
88/* TODO: Implement this function */ 86/* TODO: Implement this function */
89static void lcd_delay(int x) 87static void lcd_delay(int x)
90{ 88{
91 (void)x; 89 /* This is just arbitrary - the OF does something more complex */
90 x *= 1024;
91 while (x--);
92} 92}
93 93
94/* DBOP initialisation, do what OF does */ 94/* DBOP initialisation, do what OF does */
95static void ams3525_dbop_init(void) 95static void ams3525_dbop_init(void)
96{ 96{
97 97 /* TODO: The OF calls some other functions here, but maybe not important */
98 /* TODO: More... */
99 98
100 DBOP_TIMPOL_01 = 0xe167e167; 99 DBOP_TIMPOL_01 = 0xe167e167;
101 DBOP_TIMPOL_23 = 0xe167006e; 100 DBOP_TIMPOL_23 = 0xe167006e;
@@ -109,35 +108,43 @@ static void ams3525_dbop_init(void)
109 DBOP_TIMPOL_01 = 0x6e167; 108 DBOP_TIMPOL_01 = 0x6e167;
110 DBOP_TIMPOL_23 = 0xa167e06f; 109 DBOP_TIMPOL_23 = 0xa167e06f;
111 110
112 /* TODO: More... */ 111 /* TODO: The OF calls some other functions here, but maybe not important */
113} 112}
114 113
115static void lcd_write_reg(int reg, int value) 114
115static void lcd_write_cmd(int cmd)
116{ 116{
117 /* Write register */
117 DBOP_CTRL &= ~(1<<14); 118 DBOP_CTRL &= ~(1<<14);
118 119
119 DBOP_TIMPOL_23 = 0xa167006e; 120 DBOP_TIMPOL_23 = 0xa167006e;
120 121
121 DBOP_DOUT = reg; 122 DBOP_DOUT = cmd;
122 123
123 /* Wait for fifo to empty */ 124 /* Wait for fifo to empty */
124 while ((DBOP_STAT & (1<<10)) == 0); 125 while ((DBOP_STAT & (1<<10)) == 0);
125 126
126 DBOP_TIMPOL_23 = 0xa167e06f; 127 DBOP_TIMPOL_23 = 0xa167e06f;
127
128
129 DBOP_DOUT = value;
130
131 /* Wait for fifo to empty */
132 while ((DBOP_STAT & (1<<10)) == 0);
133} 128}
134 129
135void lcd_write_data(const fb_data* p_bytes, int count) 130void lcd_write_data(const fb_data* p_bytes, int count)
136{ 131{
137 (void)p_bytes; 132 while (count--)
138 (void)count; 133 {
134 DBOP_DOUT = *p_bytes++;
135
136 /* Wait for fifo to empty */
137 while ((DBOP_STAT & (1<<10)) == 0);
138 }
139} 139}
140 140
141static void lcd_write_reg(int reg, int value)
142{
143 unsigned short data = value;
144
145 lcd_write_cmd(reg);
146 lcd_write_data(&data, 1);
147}
141 148
142/*** hardware configuration ***/ 149/*** hardware configuration ***/
143 150
@@ -161,7 +168,7 @@ static void flip_lcd(bool yesno)
161void lcd_set_flip(bool yesno) 168void lcd_set_flip(bool yesno)
162{ 169{
163 display_flipped = yesno; 170 display_flipped = yesno;
164 xoffset = yesno ? 4 : 0; 171 y_offset = yesno ? 4 : 0; /* FIXME: Is a y_offset needed? */
165 172
166 if (display_on) 173 if (display_on)
167 flip_lcd(yesno); 174 flip_lcd(yesno);
@@ -277,42 +284,42 @@ static void _display_on(void)
277/* LCD init */ 284/* LCD init */
278void lcd_init_device(void) 285void lcd_init_device(void)
279{ 286{
280 ams3525_dbop_init(); 287 ams3525_dbop_init();
281 288
282 /* Init GPIOs the same as the OF */ 289 /* Init GPIOs the same as the OF */
283 290
284 GPIOA_DIR |= (1<<5); 291 GPIOA_DIR |= (1<<5);
285 GPIOA_PIN(5) = 0; 292 GPIOA_PIN(5) = 0;
286 293
287 GPIOA_PIN(3) = (1<<3); 294 GPIOA_PIN(3) = (1<<3);
288 295
289 GPIOA_DIR |= (3<<3); 296 GPIOA_DIR |= (3<<3);
290 297
291 GPIOA_PIN(3) = (1<<3); 298 GPIOA_PIN(3) = (1<<3);
292 299
293 GPIOA_PIN(4) = 0; //c80b0040 := 0; 300 GPIOA_PIN(4) = 0; //c80b0040 := 0;
294 301
295 GPIOA_DIR |= (1<<7); 302 GPIOA_DIR |= (1<<7);
296 GPIOA_PIN(7) = 0; 303 GPIOA_PIN(7) = 0;
297 304
298 CCU_IO &= ~(1<<2); 305 CCU_IO &= ~(1<<2);
299 CCU_IO &= ~(1<<3); 306 CCU_IO &= ~(1<<3);
300 307
301 GPIOD_DIR |= (1<<7); 308 GPIOD_DIR |= (1<<7);
302 309
303#if 0 310#if 0
304 /* TODO: This code is conditional on a variable in the OF init, we need to 311 /* TODO: This code is conditional on a variable in the OF init, we need to
305 work out what it means */ 312 work out what it means */
306 313
307 GPIOD_PIN(7) = (1<<7); 314 GPIOD_PIN(7) = (1<<7);
308 GPIOD_DIR |= (1<<7); 315 GPIOD_DIR |= (1<<7);
309#endif 316#endif
310 317
311 lcd_delay(1); 318 lcd_delay(1);
312 319
313 GPIOA_PIN(5) = (1<<5); 320 GPIOA_PIN(5) = (1<<5);
314 321
315 lcd_delay(1); 322 lcd_delay(1);
316 323
317 _display_on(); 324 _display_on();
318} 325}
@@ -361,25 +368,64 @@ void lcd_blit_yuv(unsigned char * const src[3],
361 368
362/* Update the display. 369/* Update the display.
363 This must be called after all other LCD functions that change the display. */ 370 This must be called after all other LCD functions that change the display. */
364void lcd_update(void) ICODE_ATTR;
365void lcd_update(void) 371void lcd_update(void)
366{ 372{
367 if(display_on){ 373 if (!display_on)
368 /* TODO */ 374 return;
369 } 375
370} 376 lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_SOLID_VERT);
377
378 /* Set start position and window */
379 lcd_write_reg(R_HORIZ_RAM_ADDR_POS,
380 ((y_offset + LCD_HEIGHT-1) << 8) | y_offset);
381 lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_WIDTH-1) << 8);
382 lcd_write_reg(R_RAM_ADDR_SET, y_offset);
383
384 lcd_write_cmd(R_WRITE_DATA_2_GRAM);
385
386 lcd_write_data((unsigned short *)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT);
387} /* lcd_update */
371 388
372 389
373/* Update a fraction of the display. */ 390/* Update a fraction of the display. */
374void lcd_update_rect(int, int, int, int) ICODE_ATTR;
375void lcd_update_rect(int x, int y, int width, int height) 391void lcd_update_rect(int x, int y, int width, int height)
376{ 392{
377 (void)x; 393 int ymax;
378 (void)y; 394 const unsigned short *ptr;
379 (void)width; 395
380 (void)height; 396 if (!display_on)
381 397 return;
382 if(display_on) { 398
383 /* TODO */ 399 if (x + width > LCD_WIDTH)
400 width = LCD_WIDTH - x; /* Clip right */
401 if (x < 0)
402 width += x, x = 0; /* Clip left */
403 if (width <= 0)
404 return; /* nothing left to do */
405
406 ymax = y + height;
407 if (ymax > LCD_HEIGHT)
408 ymax = LCD_HEIGHT; /* Clip bottom */
409 if (y < 0)
410 y = 0; /* Clip top */
411 if (y >= ymax)
412 return; /* nothing left to do */
413
414 lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_SOLID_VERT);
415 /* Set start position and window */
416 lcd_write_reg(R_HORIZ_RAM_ADDR_POS,
417 ((y_offset + LCD_HEIGHT-1) << 8) | y_offset);
418 lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x);
419 lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | (y + y_offset));
420
421 lcd_write_cmd(R_WRITE_DATA_2_GRAM);
422
423 ptr = (unsigned short *)&lcd_framebuffer[y][x];
424
425 do
426 {
427 lcd_write_data(ptr, width);
428 ptr += LCD_WIDTH;
384 } 429 }
385} 430 while (++y < ymax);
431} /* lcd_update_rect */