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/drivers/lcd.c | |
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/drivers/lcd.c')
-rw-r--r-- | firmware/drivers/lcd.c | 383 |
1 files changed, 165 insertions, 218 deletions
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 | |||