diff options
author | Jens Arnold <amiconn@rockbox.org> | 2004-04-21 09:39:29 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2004-04-21 09:39:29 +0000 |
commit | 38e8a117aa6b5173f43a6ef8c2841b89f41a097d (patch) | |
tree | cf4b84e83a5ab59fd67f2b7f9530afc1f7d2da99 /firmware | |
parent | 75b575a75014f886caef57a8faf6582252bfb9ed (diff) | |
download | rockbox-38e8a117aa6b5173f43a6ef8c2841b89f41a097d.tar.gz rockbox-38e8a117aa6b5173f43a6ef8c2841b89f41a097d.zip |
Unified usage of lcd transfer code
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4536 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/lcd-player.c | 36 | ||||
-rw-r--r-- | firmware/drivers/lcd-recorder.c | 60 | ||||
-rw-r--r-- | firmware/drivers/lcd.c | 383 | ||||
-rw-r--r-- | firmware/export/lcd.h | 2 |
4 files changed, 215 insertions, 266 deletions
diff --git a/firmware/drivers/lcd-player.c b/firmware/drivers/lcd-player.c index 90e1d48e00..d040342862 100644 --- a/firmware/drivers/lcd-player.c +++ b/firmware/drivers/lcd-player.c | |||
@@ -111,6 +111,8 @@ static char lcd_cram; | |||
111 | static char lcd_pram; | 111 | static char lcd_pram; |
112 | static char lcd_iram; | 112 | static char lcd_iram; |
113 | 113 | ||
114 | static unsigned char lcd_data_byte; /* global write buffer */ | ||
115 | |||
114 | unsigned short buffer_xlcd[11][2]; | 116 | unsigned short buffer_xlcd[11][2]; |
115 | unsigned short buffer_lcd_mirror[11][2]; | 117 | unsigned short buffer_lcd_mirror[11][2]; |
116 | 118 | ||
@@ -122,7 +124,7 @@ unsigned char hardware_buffer_lcd[11][2]; | |||
122 | static void lcd_free_pat(int map_ch) | 124 | static void lcd_free_pat(int map_ch) |
123 | { | 125 | { |
124 | int x, y; | 126 | int x, y; |
125 | unsigned short substitute_char; | 127 | unsigned char substitute_char; |
126 | 128 | ||
127 | int pat; | 129 | int pat; |
128 | pat=extended_chars_mapped[map_ch]; | 130 | pat=extended_chars_mapped[map_ch]; |
@@ -140,8 +142,8 @@ static void lcd_free_pat(int map_ch) | |||
140 | #ifdef SIMULATOR | 142 | #ifdef SIMULATOR |
141 | hardware_buffer_lcd[x][y]=substitute_char; | 143 | hardware_buffer_lcd[x][y]=substitute_char; |
142 | #else | 144 | #else |
143 | lcd_write(true, LCD_CURSOR(x, y)); | 145 | lcd_write_command(LCD_CURSOR(x, y)); |
144 | lcd_write(false, substitute_char); | 146 | lcd_write_data(&substitute_char, 1); |
145 | #endif | 147 | #endif |
146 | } | 148 | } |
147 | } | 149 | } |
@@ -240,8 +242,8 @@ void xlcd_update(void) | |||
240 | #ifdef SIMULATOR | 242 | #ifdef SIMULATOR |
241 | hardware_buffer_lcd[x][y]=hw_ch; | 243 | hardware_buffer_lcd[x][y]=hw_ch; |
242 | #else | 244 | #else |
243 | lcd_write(true,LCD_CURSOR(x,y)); | 245 | lcd_write_command(LCD_CURSOR(x,y)); |
244 | lcd_write(false, hw_ch); | 246 | lcd_write_data(&hw_ch, 1); |
245 | #endif | 247 | #endif |
246 | } | 248 | } |
247 | } | 249 | } |
@@ -274,8 +276,9 @@ bool lcdx_putc(int x, int y, unsigned short ch) | |||
274 | #ifdef SIMULATOR | 276 | #ifdef SIMULATOR |
275 | hardware_buffer_lcd[x][y]=lcd_char; | 277 | hardware_buffer_lcd[x][y]=lcd_char; |
276 | #else | 278 | #else |
277 | lcd_write(true, LCD_CURSOR(x, y)); | 279 | lcd_data_byte = (unsigned char) lcd_char; |
278 | lcd_write(false, lcd_char); | 280 | lcd_write_command(LCD_CURSOR(x, y)); |
281 | lcd_write_data(&lcd_data_byte, 1); | ||
279 | #endif | 282 | #endif |
280 | return false; | 283 | return false; |
281 | } | 284 | } |
@@ -405,16 +408,14 @@ void lcd_define_pattern(int pat, char *pattern) | |||
405 | #ifndef SIMULATOR | 408 | #ifndef SIMULATOR |
406 | void lcd_define_hw_pattern (int which,char *pattern,int length) | 409 | void lcd_define_hw_pattern (int which,char *pattern,int length) |
407 | { | 410 | { |
408 | int i; | 411 | lcd_write_command(lcd_pram | which); |
409 | lcd_write(true,lcd_pram | which); | 412 | lcd_write_data(pattern, length); |
410 | for (i=0;i<length;i++) | ||
411 | lcd_write(false,pattern[i]); | ||
412 | } | 413 | } |
413 | 414 | ||
414 | void lcd_double_height(bool on) | 415 | void lcd_double_height(bool on) |
415 | { | 416 | { |
416 | if(new_lcd) | 417 | if(new_lcd) |
417 | lcd_write(true,on?9:8); | 418 | lcd_write_command(on?9:8); |
418 | } | 419 | } |
419 | 420 | ||
420 | static char icon_pos[] = | 421 | static char icon_pos[] = |
@@ -463,20 +464,21 @@ void lcd_icon(int icon, bool enable) | |||
463 | pos = icon_pos[icon]; | 464 | pos = icon_pos[icon]; |
464 | mask = icon_mask[icon]; | 465 | mask = icon_mask[icon]; |
465 | 466 | ||
466 | lcd_write(true, LCD_ICON(pos)); | 467 | lcd_write_command(LCD_ICON(pos)); |
467 | 468 | ||
468 | if(enable) | 469 | if(enable) |
469 | icon_mirror[pos] |= mask; | 470 | icon_mirror[pos] |= mask; |
470 | else | 471 | else |
471 | icon_mirror[pos] &= ~mask; | 472 | icon_mirror[pos] &= ~mask; |
472 | 473 | ||
473 | lcd_write(false, icon_mirror[pos]); | 474 | lcd_write_data(&icon_mirror[pos], 1); |
474 | } | 475 | } |
475 | 476 | ||
476 | void lcd_set_contrast(int val) | 477 | void lcd_set_contrast(int val) |
477 | { | 478 | { |
478 | lcd_write(true, lcd_contrast_set); | 479 | lcd_data_byte = (unsigned char) (31 - val); |
479 | lcd_write(false, 31-val); | 480 | lcd_write_command(lcd_contrast_set); |
481 | lcd_write_data(&lcd_data_byte, 1); | ||
480 | } | 482 | } |
481 | #endif /* SIMULATOR */ | 483 | #endif /* SIMULATOR */ |
482 | 484 | ||
@@ -763,7 +765,7 @@ void lcd_cursor(int x, int y) | |||
763 | value=0x80|(x+0x54); | 765 | value=0x80|(x+0x54); |
764 | break; | 766 | break; |
765 | } | 767 | } |
766 | lcd_write(true,value); | 768 | lcd_write_command(value); |
767 | } | 769 | } |
768 | #endif | 770 | #endif |
769 | 771 | ||
diff --git a/firmware/drivers/lcd-recorder.c b/firmware/drivers/lcd-recorder.c index f7eb529fea..8cf5f12b8b 100644 --- a/firmware/drivers/lcd-recorder.c +++ b/firmware/drivers/lcd-recorder.c | |||
@@ -143,19 +143,19 @@ void lcd_init (void) | |||
143 | PBIOR |= 0x000f; /* IOR = 1 */ | 143 | PBIOR |= 0x000f; /* IOR = 1 */ |
144 | 144 | ||
145 | /* inits like the original firmware */ | 145 | /* inits like the original firmware */ |
146 | lcd_write(true, LCD_SOFTWARE_RESET); | 146 | lcd_write_command(LCD_SOFTWARE_RESET); |
147 | lcd_write(true, LCD_SET_INTERNAL_REGULATOR_RESISTOR_RATIO + 4); | 147 | lcd_write_command(LCD_SET_INTERNAL_REGULATOR_RESISTOR_RATIO + 4); |
148 | lcd_write(true, LCD_SET_1OVER4_BIAS_RATIO + 0); /* force 1/4 bias: 0 */ | 148 | lcd_write_command(LCD_SET_1OVER4_BIAS_RATIO + 0); /* force 1/4 bias: 0 */ |
149 | lcd_write(true, LCD_SET_POWER_CONTROL_REGISTER + 7); /* power control register: op-amp=1, regulator=1, booster=1 */ | 149 | lcd_write_command(LCD_SET_POWER_CONTROL_REGISTER + 7); /* power control register: op-amp=1, regulator=1, booster=1 */ |
150 | lcd_write(true, LCD_SET_DISPLAY_ON); | 150 | lcd_write_command(LCD_SET_DISPLAY_ON); |
151 | lcd_write(true, LCD_SET_NORMAL_DISPLAY); | 151 | lcd_write_command(LCD_SET_NORMAL_DISPLAY); |
152 | lcd_write(true, LCD_SET_SEGMENT_REMAP + 1); /* mirror horizontal: 1 */ | 152 | lcd_write_command(LCD_SET_SEGMENT_REMAP + 1); /* mirror horizontal: 1 */ |
153 | lcd_write(true, LCD_SET_COM_OUTPUT_SCAN_DIRECTION + 8); /* mirror vertical: 1 */ | 153 | lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION + 8); /* mirror vertical: 1 */ |
154 | lcd_write(true, LCD_SET_DISPLAY_START_LINE + 0); | 154 | lcd_write_command(LCD_SET_DISPLAY_START_LINE + 0); |
155 | lcd_set_contrast(lcd_default_contrast()); | 155 | lcd_set_contrast(lcd_default_contrast()); |
156 | lcd_write(true, LCD_SET_PAGE_ADDRESS); | 156 | lcd_write_command(LCD_SET_PAGE_ADDRESS); |
157 | lcd_write(true, LCD_SET_LOWER_COLUMN_ADDRESS + 0); | 157 | lcd_write_command(LCD_SET_LOWER_COLUMN_ADDRESS + 0); |
158 | lcd_write(true, LCD_SET_HIGHER_COLUMN_ADDRESS + 0); | 158 | lcd_write_command(LCD_SET_HIGHER_COLUMN_ADDRESS + 0); |
159 | 159 | ||
160 | lcd_clear_display(); | 160 | lcd_clear_display(); |
161 | lcd_update(); | 161 | lcd_update(); |
@@ -171,9 +171,9 @@ void lcd_blit (unsigned char* p_data, int x, int y, int width, int height, int s | |||
171 | /* Copy display bitmap to hardware */ | 171 | /* Copy display bitmap to hardware */ |
172 | while (height--) | 172 | while (height--) |
173 | { | 173 | { |
174 | lcd_write (true, LCD_CNTL_PAGE | (y++ & 0xf)); | 174 | lcd_write_command (LCD_CNTL_PAGE | (y++ & 0xf)); |
175 | lcd_write (true, LCD_CNTL_HIGHCOL | (((x+xoffset)>>4) & 0xf)); | 175 | lcd_write_command (LCD_CNTL_HIGHCOL | (((x+xoffset)>>4) & 0xf)); |
176 | lcd_write (true, LCD_CNTL_LOWCOL | ((x+xoffset) & 0xf)); | 176 | lcd_write_command (LCD_CNTL_LOWCOL | ((x+xoffset) & 0xf)); |
177 | 177 | ||
178 | lcd_write_data(p_data, width); | 178 | lcd_write_data(p_data, width); |
179 | p_data += stride; | 179 | p_data += stride; |
@@ -193,9 +193,9 @@ void lcd_update (void) | |||
193 | /* Copy display bitmap to hardware */ | 193 | /* Copy display bitmap to hardware */ |
194 | for (y = 0; y < LCD_HEIGHT/8; y++) | 194 | for (y = 0; y < LCD_HEIGHT/8; y++) |
195 | { | 195 | { |
196 | lcd_write (true, LCD_CNTL_PAGE | (y & 0xf)); | 196 | lcd_write_command (LCD_CNTL_PAGE | (y & 0xf)); |
197 | lcd_write (true, LCD_CNTL_HIGHCOL | ((xoffset>>4) & 0xf)); | 197 | lcd_write_command (LCD_CNTL_HIGHCOL | ((xoffset>>4) & 0xf)); |
198 | lcd_write (true, LCD_CNTL_LOWCOL | (xoffset & 0xf)); | 198 | lcd_write_command (LCD_CNTL_LOWCOL | (xoffset & 0xf)); |
199 | 199 | ||
200 | lcd_write_data (lcd_framebuffer[y], LCD_WIDTH); | 200 | lcd_write_data (lcd_framebuffer[y], LCD_WIDTH); |
201 | } | 201 | } |
@@ -224,9 +224,9 @@ void lcd_update_rect (int x_start, int y, | |||
224 | /* Copy specified rectange bitmap to hardware */ | 224 | /* Copy specified rectange bitmap to hardware */ |
225 | for (; y <= ymax; y++) | 225 | for (; y <= ymax; y++) |
226 | { | 226 | { |
227 | lcd_write (true, LCD_CNTL_PAGE | (y & 0xf)); | 227 | lcd_write_command (LCD_CNTL_PAGE | (y & 0xf)); |
228 | lcd_write (true, LCD_CNTL_HIGHCOL | (((x_start+xoffset)>>4) & 0xf)); | 228 | lcd_write_command (LCD_CNTL_HIGHCOL | (((x_start+xoffset)>>4) & 0xf)); |
229 | lcd_write (true, LCD_CNTL_LOWCOL | ((x_start+xoffset) & 0xf)); | 229 | lcd_write_command (LCD_CNTL_LOWCOL | ((x_start+xoffset) & 0xf)); |
230 | 230 | ||
231 | lcd_write_data (&lcd_framebuffer[y][x_start], width); | 231 | lcd_write_data (&lcd_framebuffer[y][x_start], width); |
232 | } | 232 | } |
@@ -234,16 +234,16 @@ void lcd_update_rect (int x_start, int y, | |||
234 | 234 | ||
235 | void lcd_set_contrast(int val) | 235 | void lcd_set_contrast(int val) |
236 | { | 236 | { |
237 | lcd_write(true, LCD_CNTL_CONTRAST); | 237 | lcd_write_command(LCD_CNTL_CONTRAST); |
238 | lcd_write(true, val); | 238 | lcd_write_command(val); |
239 | } | 239 | } |
240 | 240 | ||
241 | void lcd_set_invert_display(bool yesno) | 241 | void lcd_set_invert_display(bool yesno) |
242 | { | 242 | { |
243 | if (yesno) | 243 | if (yesno) |
244 | lcd_write(true, LCD_SET_REVERSE_DISPLAY); | 244 | lcd_write_command(LCD_SET_REVERSE_DISPLAY); |
245 | else | 245 | else |
246 | lcd_write(true, LCD_SET_NORMAL_DISPLAY); | 246 | lcd_write_command(LCD_SET_NORMAL_DISPLAY); |
247 | } | 247 | } |
248 | 248 | ||
249 | /* turn the display upside down (call lcd_update() afterwards) */ | 249 | /* turn the display upside down (call lcd_update() afterwards) */ |
@@ -251,14 +251,14 @@ void lcd_set_flip(bool yesno) | |||
251 | { | 251 | { |
252 | if (yesno) | 252 | if (yesno) |
253 | { | 253 | { |
254 | lcd_write(true, LCD_SET_SEGMENT_REMAP); | 254 | lcd_write_command(LCD_SET_SEGMENT_REMAP); |
255 | lcd_write(true, LCD_SET_COM_OUTPUT_SCAN_DIRECTION); | 255 | lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION); |
256 | xoffset = 132 - LCD_WIDTH; /* 132 colums minus the 112 we have */ | 256 | xoffset = 132 - LCD_WIDTH; /* 132 colums minus the 112 we have */ |
257 | } | 257 | } |
258 | else | 258 | else |
259 | { | 259 | { |
260 | lcd_write(true, LCD_SET_SEGMENT_REMAP | 0x01); | 260 | lcd_write_command(LCD_SET_SEGMENT_REMAP | 0x01); |
261 | lcd_write(true, LCD_SET_COM_OUTPUT_SCAN_DIRECTION | 0x08); | 261 | lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION | 0x08); |
262 | xoffset = 0; | 262 | xoffset = 0; |
263 | } | 263 | } |
264 | } | 264 | } |
@@ -274,7 +274,7 @@ void lcd_set_flip(bool yesno) | |||
274 | */ | 274 | */ |
275 | void lcd_roll(int lines) | 275 | void lcd_roll(int lines) |
276 | { | 276 | { |
277 | lcd_write(true, LCD_SET_DISPLAY_START_LINE | (lines & (LCD_HEIGHT-1))); | 277 | lcd_write_command(LCD_SET_DISPLAY_START_LINE | (lines & (LCD_HEIGHT-1))); |
278 | } | 278 | } |
279 | 279 | ||
280 | #endif /* SIMULATOR */ | 280 | #endif /* SIMULATOR */ |
diff --git a/firmware/drivers/lcd.c b/firmware/drivers/lcd.c index 252652b29a..0df831e259 100644 --- a/firmware/drivers/lcd.c +++ b/firmware/drivers/lcd.c | |||
@@ -82,104 +82,50 @@ | |||
82 | * | 82 | * |
83 | */ | 83 | */ |
84 | 84 | ||
85 | void lcd_write(bool command, int byte) __attribute__ ((section (".icode"))); | 85 | void lcd_write_command(int byte) __attribute__ ((section (".icode"))); |
86 | void lcd_write(bool command, int byte) | 86 | void lcd_write_command(int byte) |
87 | { | 87 | { |
88 | asm("and.b %0, @(r0,gbr)" | 88 | asm ( |
89 | : | 89 | "and.b %0, @(r0,gbr)" |
90 | : /* %0 */ "I"(~(LCD_CS|LCD_DS|LCD_SD|LCD_SC)), | 90 | : /* outputs */ |
91 | /* %1 */ "z"(LCDR)); | 91 | : /* inputs */ |
92 | 92 | /* %0 */ "I"(~(LCD_CS|LCD_DS|LCD_SD|LCD_SC)), | |
93 | if (command) | 93 | /* %1 = r0 */ "z"(LCDR) |
94 | asm ("shll8 %0\n" | 94 | ); |
95 | "0: \n\t" | 95 | |
96 | "and.b %2,@(r0,gbr)\n\t" | 96 | asm ( |
97 | "shll %0\n\t" | 97 | "0: \n" |
98 | "bf 1f\n\t" | 98 | "and.b %2,@(r0,gbr) \n" |
99 | "or.b %3,@(r0,gbr)\n" | 99 | "shll %0 \n" |
100 | "1: \n\t" | 100 | "bf 1f \n" |
101 | "or.b %4,@(r0,gbr)\n" | 101 | "or.b %3,@(r0,gbr) \n" |
102 | "add #-1,%1\n\t" | 102 | "1: \n" |
103 | "cmp/pl %1\n\t" | 103 | "or.b %4,@(r0,gbr) \n" |
104 | "bt 0b" | 104 | "add #-1,%1 \n" |
105 | : | 105 | "cmp/pl %1 \n" |
106 | : /* %0 */ "r"(((unsigned)byte)<<16), | 106 | "bt 0b \n" |
107 | /* %1 */ "r"(8), | 107 | : /* outputs */ |
108 | /* %2 */ "I"(~(LCD_SC|LCD_SD|LCD_DS)), | 108 | : /* inputs */ |
109 | /* %3 */ "I"(LCD_SD), | 109 | /* %0 */ "r"(((unsigned)byte)<<24), |
110 | /* %4 */ "I"(LCD_SC), | 110 | /* %1 */ "r"(8), |
111 | /* %5 */ "z"(LCDR)); | 111 | /* %2 */ "I"(~(LCD_SC|LCD_SD|LCD_DS)), |
112 | else | 112 | /* %3 */ "I"(LCD_SD), |
113 | asm ("shll8 %0\n" | 113 | /* %4 */ "I"(LCD_SC), |
114 | "0: \n\t" | 114 | /* %5 = r0 */ "z"(LCDR) |
115 | "and.b %2, @(r0,gbr)\n\t" | 115 | ); |
116 | "shll %0\n\t" | 116 | |
117 | "bf 1f\n\t" | 117 | asm ( |
118 | "or.b %3, @(r0,gbr)\n" | 118 | "or.b %0, @(r0,gbr)" |
119 | "1: \n\t" | 119 | : /* outputs */ |
120 | "or.b %4, @(r0,gbr)\n" | 120 | : /* inputs */ |
121 | "and.b %2, @(r0,gbr)\n\t" | 121 | /* %0 */ "I"(LCD_CS|LCD_DS|LCD_SD|LCD_SC), |
122 | "shll %0\n\t" | 122 | /* %1 = r0 */ "z"(LCDR) |
123 | "bf 1f\n\t" | 123 | ); |
124 | "or.b %3, @(r0,gbr)\n" | ||
125 | "1: \n\t" | ||
126 | "or.b %4, @(r0,gbr)\n" | ||
127 | "and.b %2, @(r0,gbr)\n\t" | ||
128 | "shll %0\n\t" | ||
129 | "bf 1f\n\t" | ||
130 | "or.b %3, @(r0,gbr)\n" | ||
131 | "1: \n\t" | ||
132 | "or.b %4, @(r0,gbr)\n" | ||
133 | "and.b %2, @(r0,gbr)\n\t" | ||
134 | "shll %0\n\t" | ||
135 | "bf 1f\n\t" | ||
136 | "or.b %3, @(r0,gbr)\n" | ||
137 | "1: \n\t" | ||
138 | "or.b %4, @(r0,gbr)\n" | ||
139 | "and.b %2, @(r0,gbr)\n\t" | ||
140 | "shll %0\n\t" | ||
141 | "bf 1f\n\t" | ||
142 | "or.b %3, @(r0,gbr)\n" | ||
143 | "1: \n\t" | ||
144 | "or.b %4, @(r0,gbr)\n" | ||
145 | "and.b %2, @(r0,gbr)\n\t" | ||
146 | "shll %0\n\t" | ||
147 | "bf 1f\n\t" | ||
148 | "or.b %3, @(r0,gbr)\n" | ||
149 | "1: \n\t" | ||
150 | "or.b %4, @(r0,gbr)\n" | ||
151 | "and.b %2, @(r0,gbr)\n\t" | ||
152 | "shll %0\n\t" | ||
153 | "bf 1f\n\t" | ||
154 | "or.b %3, @(r0,gbr)\n" | ||
155 | "1: \n\t" | ||
156 | "or.b %4, @(r0,gbr)\n" | ||
157 | "and.b %2, @(r0,gbr)\n\t" | ||
158 | "shll %0\n\t" | ||
159 | "bf 1f\n\t" | ||
160 | "or.b %3, @(r0,gbr)\n" | ||
161 | "1: \n\t" | ||
162 | "or.b %4, @(r0,gbr)\n" | ||
163 | : | ||
164 | : /* %0 */ "r"(((unsigned)byte)<<16), | ||
165 | /* %1 */ "r"(8), | ||
166 | /* %2 */ "I"(~(LCD_SC|LCD_SD)), | ||
167 | /* %3 */ "I"(LCD_SD|LCD_DS), | ||
168 | /* %4 */ "I"(LCD_SC|LCD_DS), | ||
169 | /* %5 */ "z"(LCDR)); | ||
170 | |||
171 | asm("or.b %0, @(r0,gbr)" | ||
172 | : | ||
173 | : /* %0 */ "I"(LCD_CS|LCD_DS|LCD_SD|LCD_SC), | ||
174 | /* %1 */ "z"(LCDR)); | ||
175 | } | 124 | } |
176 | 125 | ||
177 | 126 | ||
178 | /* A high performance function to write data to the display, | 127 | /* A high performance function to write data to the display, |
179 | one or multiple bytes. | 128 | one or multiple bytes. */ |
180 | Ultimately, all calls to lcd_write(false, xxx) should be substituted by | ||
181 | this, it will be most efficient if the LCD buffer is tilted to have the | ||
182 | X row as consecutive bytes, so we can write a whole row */ | ||
183 | void lcd_write_data(unsigned char* p_bytes, int count) __attribute__ ((section (".icode"))); | 129 | void lcd_write_data(unsigned char* p_bytes, int count) __attribute__ ((section (".icode"))); |
184 | 130 | ||
185 | #ifdef HAVE_LCD_CHARCELLS | 131 | #ifdef HAVE_LCD_CHARCELLS |
@@ -199,16 +145,16 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
199 | 145 | ||
200 | /* precalculate the values for later bit toggling, init data write */ | 146 | /* precalculate the values for later bit toggling, init data write */ |
201 | asm ( | 147 | asm ( |
202 | "mov.b @%2,%0\n" /* sda1 = PBDRL */ | 148 | "mov.b @%2,%0 \n" /* sda1 = PBDRL */ |
203 | "or %4,%0\n" /* sda1 |= LCD_DS | LCD_SD DS and SD high, */ | 149 | "or %4,%0 \n" /* sda1 |= LCD_DS | LCD_SD DS and SD high, */ |
204 | "and %3,%0\n" /* sda1 &= ~(LCD_CS | LCD_SC) CS and SC low */ | 150 | "and %3,%0 \n" /* sda1 &= ~(LCD_CS | LCD_SC) CS and SC low */ |
205 | "mov %0,%1\n" /* sda1 -> clk0sda0 */ | 151 | "mov %0,%1 \n" /* sda1 -> clk0sda0 */ |
206 | "and %5,%1\n" /* clk0sda0 &= ~LCD_SD both low */ | 152 | "and %5,%1 \n" /* clk0sda0 &= ~LCD_SD both low */ |
207 | "mov.b %1,@%2\n" /* PBDRL = clk0sda0 */ | 153 | "mov.b %1,@%2 \n" /* PBDRL = clk0sda0 */ |
208 | : // outputs | 154 | : /* outputs */ |
209 | /* %0 */ "=r"(sda1), | 155 | /* %0 */ "=r"(sda1), |
210 | /* %1 */ "=r"(clk0sda0) | 156 | /* %1 */ "=r"(clk0sda0) |
211 | : // inputs | 157 | : /* inputs */ |
212 | /* %2 */ "r"(LCDR), | 158 | /* %2 */ "r"(LCDR), |
213 | /* %3 */ "r"(~(LCD_CS | LCD_SC)), | 159 | /* %3 */ "r"(~(LCD_CS | LCD_SC)), |
214 | /* %4 */ "r"(LCD_DS | LCD_SD), | 160 | /* %4 */ "r"(LCD_DS | LCD_SD), |
@@ -217,72 +163,71 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
217 | 163 | ||
218 | /* unrolled loop to serialize the byte */ | 164 | /* unrolled loop to serialize the byte */ |
219 | asm ( | 165 | asm ( |
220 | "mov %4,r0\n" /* we need &PBDRL in r0 for "or.b x,@(r0,gbr)" */ | 166 | "shll %0 \n" /* shift the MSB into carry */ |
221 | 167 | ||
222 | "shll %0\n" /* shift the MSB into carry */ | 168 | "bf 1f \n" |
223 | "bf 1f\n" | 169 | "mov.b %1,@%4 \n" /* if it was a "1": set SD high, SC low still */ |
224 | "mov.b %1,@%4\n" /* if it was a "1": set SD high, SC low still */ | 170 | "1: \n" |
225 | "1: \n" | 171 | "or.b %2,@(r0,gbr) \n" /* rise SC (independent of SD level) */ |
226 | "or.b %2, @(r0,gbr)\n" /* rise SC (independent of SD level) */ | 172 | "shll %0 \n" /* shift for next round, now for longer hold time */ |
227 | "shll %0\n" /* shift for next round, now for longer hold time */ | 173 | "mov.b %3,@%4 \n" /* SC and SD low again */ |
228 | "mov.b %3,@%4\n" /* SC and SD low again */ | 174 | |
229 | 175 | "bf 1f \n" | |
230 | "bf 1f\n" | 176 | "mov.b %1,@%4 \n" |
231 | "mov.b %1,@%4\n" | 177 | "1: \n" |
232 | "1: \n" | 178 | "or.b %2,@(r0,gbr) \n" |
233 | "or.b %2, @(r0,gbr)\n" | 179 | "shll %0 \n" |
234 | "shll %0\n" | 180 | "mov.b %3,@%4 \n" |
235 | "mov.b %3,@%4\n" | 181 | |
236 | 182 | "bf 1f \n" | |
237 | "bf 1f\n" | 183 | "mov.b %1,@%4 \n" |
238 | "mov.b %1,@%4\n" | 184 | "1: \n" |
239 | "1: \n" | 185 | "or.b %2,@(r0,gbr) \n" |
240 | "or.b %2, @(r0,gbr)\n" | 186 | "shll %0 \n" |
241 | "shll %0\n" | 187 | "mov.b %3,@%4 \n" |
242 | "mov.b %3,@%4\n" | 188 | |
243 | 189 | "bf 1f \n" | |
244 | "bf 1f\n" | 190 | "mov.b %1,@%4 \n" |
245 | "mov.b %1,@%4\n" | 191 | "1: \n" |
246 | "1: \n" | 192 | "or.b %2,@(r0,gbr) \n" |
247 | "or.b %2, @(r0,gbr)\n" | 193 | "shll %0 \n" |
248 | "shll %0\n" | 194 | "mov.b %3,@%4 \n" |
249 | "mov.b %3,@%4\n" | 195 | |
250 | 196 | "bf 1f \n" | |
251 | "bf 1f\n" | 197 | "mov.b %1,@%4 \n" |
252 | "mov.b %1,@%4\n" | 198 | "1: \n" |
253 | "1: \n" | 199 | "or.b %2,@(r0,gbr) \n" |
254 | "or.b %2, @(r0,gbr)\n" | 200 | "shll %0 \n" |
255 | "shll %0\n" | 201 | "mov.b %3,@%4 \n" |
256 | "mov.b %3,@%4\n" | 202 | |
257 | 203 | "bf 1f \n" | |
258 | "bf 1f\n" | 204 | "mov.b %1,@%4 \n" |
259 | "mov.b %1,@%4\n" | 205 | "1: \n" |
260 | "1: \n" | 206 | "or.b %2,@(r0,gbr) \n" |
261 | "or.b %2, @(r0,gbr)\n" | 207 | "shll %0 \n" |
262 | "shll %0\n" | 208 | "mov.b %3,@%4 \n" |
263 | "mov.b %3,@%4\n" | 209 | |
264 | 210 | "bf 1f \n" | |
265 | "bf 1f\n" | 211 | "mov.b %1,@%4 \n" |
266 | "mov.b %1,@%4\n" | 212 | "1: \n" |
267 | "1: \n" | 213 | "or.b %2,@(r0,gbr) \n" |
268 | "or.b %2, @(r0,gbr)\n" | 214 | "shll %0 \n" |
269 | "shll %0\n" | 215 | "mov.b %3,@%4 \n" |
270 | "mov.b %3,@%4\n" | 216 | |
271 | 217 | "bf 1f \n" | |
272 | "bf 1f\n" | 218 | "mov.b %1,@%4 \n" /* set SD high, SC low still */ |
273 | "mov.b %1,@%4\n" /* set SD high, SC low still */ | 219 | "1: \n" |
274 | "1: \n" | 220 | "or.b %2,@(r0,gbr) \n" /* rise SC (independent of SD level) */ |
275 | "or.b %2, @(r0,gbr)\n" /* rise SC (independent of SD level) */ | 221 | |
276 | 222 | "or.b %5,@(r0,gbr) \n" /* restore port */ | |
277 | "or.b %5, @(r0,gbr)\n" /* restore port */ | 223 | : /* outputs */ |
278 | : | 224 | : /* inputs */ |
279 | : /* %0 */ "r"(byte), | 225 | /* %0 */ "r"(byte), |
280 | /* %1 */ "r"(sda1), | 226 | /* %1 */ "r"(sda1), |
281 | /* %2 */ "I"(LCD_SC), | 227 | /* %2 */ "I"(LCD_SC), |
282 | /* %3 */ "r"(clk0sda0), | 228 | /* %3 */ "r"(clk0sda0), |
283 | /* %4 */ "r"(LCDR), | 229 | /* %4 = r0 */ "z"(LCDR), |
284 | /* %5 */ "I"(LCD_CS|LCD_DS|LCD_SD|LCD_SC) | 230 | /* %5 */ "I"(LCD_CS|LCD_DS|LCD_SD|LCD_SC) |
285 | : "r0" | ||
286 | ); | 231 | ); |
287 | 232 | ||
288 | /* This is the place to reenable the interrupts, if we have disabled | 233 | /* This is the place to reenable the interrupts, if we have disabled |
@@ -309,11 +254,11 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
309 | 254 | ||
310 | /* precalculate the values for later bit toggling, init data write */ | 255 | /* precalculate the values for later bit toggling, init data write */ |
311 | asm ( | 256 | asm ( |
312 | "mov.b @%1,r0\n" /* r0 = PBDRL */ | 257 | "mov.b @%1,r0 \n" /* r0 = PBDRL */ |
313 | "or %3,r0\n" /* r0 |= LCD_DS | LCD_SD DS and SD high, */ | 258 | "or %3,r0 \n" /* r0 |= LCD_DS | LCD_SD DS and SD high, */ |
314 | "and %2,r0\n" /* r0 &= ~(LCD_CS | LCD_SC) CS and SC low */ | 259 | "and %2,r0 \n" /* r0 &= ~(LCD_CS | LCD_SC) CS and SC low */ |
315 | "mov.b r0,@%1\n" /* PBDRL = r0 */ | 260 | "mov.b r0,@%1 \n" /* PBDRL = r0 */ |
316 | "neg r0,%0\n" /* sda1 = 0-r0 */ | 261 | "neg r0,%0 \n" /* sda1 = 0-r0 */ |
317 | : /* outputs: */ | 262 | : /* outputs: */ |
318 | /* %0 */ "=r"(sda1) | 263 | /* %0 */ "=r"(sda1) |
319 | : /* inputs: */ | 264 | : /* inputs: */ |
@@ -326,56 +271,56 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
326 | 271 | ||
327 | /* unrolled loop to serialize the byte */ | 272 | /* unrolled loop to serialize the byte */ |
328 | asm ( | 273 | asm ( |
329 | "shll %0 \n" /* shift the MSB into carry */ | 274 | "shll %0 \n" /* shift the MSB into carry */ |
330 | "negc %1, r0\n" /* carry to SD, SC low */ | 275 | "negc %1, r0 \n" /* carry to SD, SC low */ |
331 | "mov.b r0,@%3\n" /* set data to port */ | 276 | "mov.b r0,@%3 \n" /* set data to port */ |
332 | "or %2, r0\n" /* rise SC (independent of SD level) */ | 277 | "or %2, r0 \n" /* rise SC (independent of SD level) */ |
333 | "mov.b r0,@%3\n" /* set to port */ | 278 | "mov.b r0,@%3 \n" /* set to port */ |
334 | 279 | ||
335 | "shll %0 \n" | 280 | "shll %0 \n" |
336 | "negc %1, r0\n" | 281 | "negc %1, r0 \n" |
337 | "mov.b r0,@%3\n" | 282 | "mov.b r0,@%3 \n" |
338 | "or %2, r0\n" | 283 | "or %2, r0 \n" |
339 | "mov.b r0,@%3\n" | 284 | "mov.b r0,@%3 \n" |
340 | 285 | ||
341 | "shll %0 \n" | 286 | "shll %0 \n" |
342 | "negc %1, r0\n" | 287 | "negc %1, r0 \n" |
343 | "mov.b r0,@%3\n" | 288 | "mov.b r0,@%3 \n" |
344 | "or %2, r0\n" | 289 | "or %2, r0 \n" |
345 | "mov.b r0,@%3\n" | 290 | "mov.b r0,@%3 \n" |
346 | 291 | ||
347 | "shll %0 \n" | 292 | "shll %0 \n" |
348 | "negc %1, r0\n" | 293 | "negc %1, r0 \n" |
349 | "mov.b r0,@%3\n" | 294 | "mov.b r0,@%3 \n" |
350 | "or %2, r0\n" | 295 | "or %2, r0 \n" |
351 | "mov.b r0,@%3\n" | 296 | "mov.b r0,@%3 \n" |
352 | 297 | ||
353 | "shll %0 \n" | 298 | "shll %0 \n" |
354 | "negc %1, r0\n" | 299 | "negc %1, r0 \n" |
355 | "mov.b r0,@%3\n" | 300 | "mov.b r0,@%3 \n" |
356 | "or %2, r0\n" | 301 | "or %2, r0 \n" |
357 | "mov.b r0,@%3\n" | 302 | "mov.b r0,@%3 \n" |
358 | 303 | ||
359 | "shll %0 \n" | 304 | "shll %0 \n" |
360 | "negc %1, r0\n" | 305 | "negc %1, r0 \n" |
361 | "mov.b r0,@%3\n" | 306 | "mov.b r0,@%3 \n" |
362 | "or %2, r0\n" | 307 | "or %2, r0 \n" |
363 | "mov.b r0,@%3\n" | 308 | "mov.b r0,@%3 \n" |
364 | 309 | ||
365 | "shll %0 \n" | 310 | "shll %0 \n" |
366 | "negc %1, r0\n" | 311 | "negc %1, r0 \n" |
367 | "mov.b r0,@%3\n" | 312 | "mov.b r0,@%3 \n" |
368 | "or %2, r0\n" | 313 | "or %2, r0 \n" |
369 | "mov.b r0,@%3\n" | 314 | "mov.b r0,@%3 \n" |
370 | 315 | ||
371 | "shll %0 \n" | 316 | "shll %0 \n" |
372 | "negc %1, r0\n" | 317 | "negc %1, r0 \n" |
373 | "mov.b r0,@%3\n" | 318 | "mov.b r0,@%3 \n" |
374 | "or %2, r0\n" | 319 | "or %2, r0 \n" |
375 | "mov.b r0,@%3\n" | 320 | "mov.b r0,@%3 \n" |
376 | 321 | ||
377 | "or %4, r0\n" /* restore port */ | 322 | "or %4, r0 \n" /* restore port */ |
378 | "mov.b r0,@%3\n" | 323 | "mov.b r0,@%3 \n" |
379 | : /* outputs: */ | 324 | : /* outputs: */ |
380 | : /* inputs: */ | 325 | : /* inputs: */ |
381 | /* %0 */ "r"(byte), | 326 | /* %0 */ "r"(byte), |
@@ -393,3 +338,5 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
393 | } while (--count); /* tail loop is faster */ | 338 | } while (--count); /* tail loop is faster */ |
394 | } | 339 | } |
395 | #endif /* #ifdef HAVE_LCD_CHARCELLS */ | 340 | #endif /* #ifdef HAVE_LCD_CHARCELLS */ |
341 | |||
342 | |||
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 733efdded3..20023bf1c6 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h | |||
@@ -43,7 +43,7 @@ extern void lcd_stop_scroll(void); | |||
43 | extern void lcd_scroll_speed( int speed ); | 43 | extern void lcd_scroll_speed( int speed ); |
44 | extern void lcd_scroll_delay( int ms ); | 44 | extern void lcd_scroll_delay( int ms ); |
45 | extern void lcd_set_contrast(int val); | 45 | extern void lcd_set_contrast(int val); |
46 | extern void lcd_write( bool command, int byte ); | 46 | extern void lcd_write_command( int byte ); |
47 | extern void lcd_write_data( unsigned char* p_bytes, int count ); | 47 | extern void lcd_write_data( unsigned char* p_bytes, int count ); |
48 | extern int lcd_default_contrast(void); | 48 | extern int lcd_default_contrast(void); |
49 | 49 | ||