diff options
-rw-r--r-- | firmware/drivers/lcd.c | 174 |
1 files changed, 97 insertions, 77 deletions
diff --git a/firmware/drivers/lcd.c b/firmware/drivers/lcd.c index 0df831e259..68627f7c51 100644 --- a/firmware/drivers/lcd.c +++ b/firmware/drivers/lcd.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2002 by Alan Korr, speedup by Jörg Hohensohn | 10 | * Copyright (C) 2002 by Alan Korr, speedup by Jörg Hohensohn |
11 | * Further speedup and reorganization by Jens Arnold | ||
11 | * | 12 | * |
12 | * All files in this archive are subject to the GNU General Public License. | 13 | * 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 | * See the file COPYING in the source tree root for full license agreement. |
@@ -136,7 +137,6 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
136 | { | 137 | { |
137 | unsigned int byte; | 138 | unsigned int byte; |
138 | unsigned int sda1; /* precalculated SC=low,SD=1 */ | 139 | unsigned int sda1; /* precalculated SC=low,SD=1 */ |
139 | unsigned int clk0sda0; /* precalculated SC and SD low */ | ||
140 | 140 | ||
141 | byte = *p_bytes++ << 24; /* fetch to MSB position */ | 141 | byte = *p_bytes++ << 24; /* fetch to MSB position */ |
142 | 142 | ||
@@ -145,89 +145,108 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
145 | 145 | ||
146 | /* precalculate the values for later bit toggling, init data write */ | 146 | /* precalculate the values for later bit toggling, init data write */ |
147 | asm ( | 147 | asm ( |
148 | "mov.b @%2,%0 \n" /* sda1 = PBDRL */ | 148 | "mov.b @%1,r0 \n" /* r0 = PBDRL */ |
149 | "or %4,%0 \n" /* sda1 |= LCD_DS | LCD_SD DS and SD high, */ | 149 | "or %3,r0 \n" /* r0 |= LCD_DS | LCD_SD DS and SD high */ |
150 | "and %3,%0 \n" /* sda1 &= ~(LCD_CS | LCD_SC) CS and SC low */ | 150 | "and %2,r0 \n" /* r0 &= ~(LCD_CS | LCD_SC) CS and SC low */ |
151 | "mov %0,%1 \n" /* sda1 -> clk0sda0 */ | 151 | "mov.b r0,@%1 \n" /* PBDRL = r0 */ |
152 | "and %5,%1 \n" /* clk0sda0 &= ~LCD_SD both low */ | 152 | "mov r0,%0 \n" /* sda1 = r0 */ |
153 | "mov.b %1,@%2 \n" /* PBDRL = clk0sda0 */ | ||
154 | : /* outputs */ | 153 | : /* outputs */ |
155 | /* %0 */ "=r"(sda1), | 154 | /* %0 */ "=r"(sda1) |
156 | /* %1 */ "=r"(clk0sda0) | ||
157 | : /* inputs */ | 155 | : /* inputs */ |
158 | /* %2 */ "r"(LCDR), | 156 | /* %1 */ "r"(LCDR), |
159 | /* %3 */ "r"(~(LCD_CS | LCD_SC)), | 157 | /* %2 */ "I"(~(LCD_CS | LCD_SC)), |
160 | /* %4 */ "r"(LCD_DS | LCD_SD), | 158 | /* %3 */ "I"(LCD_DS | LCD_SD) |
161 | /* %5 */ "r"(~LCD_SD) | 159 | : /* trashed */ |
160 | "r0" | ||
162 | ); | 161 | ); |
163 | 162 | ||
164 | /* unrolled loop to serialize the byte */ | 163 | /* unrolled loop to serialize the byte */ |
165 | asm ( | 164 | asm ( |
166 | "shll %0 \n" /* shift the MSB into carry */ | 165 | "shll %0 \n" /* shift the msb into carry */ |
167 | 166 | ".align 2 \n" | |
168 | "bf 1f \n" | 167 | "mov %1,r0 \n" /* copy precalculated port value */ |
169 | "mov.b %1,@%4 \n" /* if it was a "1": set SD high, SC low still */ | 168 | "bt 1f \n" /* data bit = 1? */ |
170 | "1: \n" | 169 | "and %5,r0 \n" /* no: r0 &= ~LCD_SD */ |
171 | "or.b %2,@(r0,gbr) \n" /* rise SC (independent of SD level) */ | 170 | "1: \n" |
172 | "shll %0 \n" /* shift for next round, now for longer hold time */ | 171 | "shll %0 \n" /* next shift here for alignment */ |
173 | "mov.b %3,@%4 \n" /* SC and SD low again */ | 172 | "mov.b r0,@%3 \n" /* set data to port */ |
174 | 173 | "or %2,r0 \n" /* rise SC (independent of SD level) */ | |
175 | "bf 1f \n" | 174 | "mov.b r0,@%3 \n" /* set to port */ |
176 | "mov.b %1,@%4 \n" | 175 | |
177 | "1: \n" | 176 | "mov %1,r0 \n" |
178 | "or.b %2,@(r0,gbr) \n" | 177 | "bt 1f \n" |
179 | "shll %0 \n" | 178 | "and %5,r0 \n" |
180 | "mov.b %3,@%4 \n" | 179 | "1: \n" |
181 | 180 | "mov.b r0,@%3 \n" | |
182 | "bf 1f \n" | 181 | "or %2,r0 \n" |
183 | "mov.b %1,@%4 \n" | 182 | "mov.b r0,@%3 \n" |
184 | "1: \n" | 183 | |
185 | "or.b %2,@(r0,gbr) \n" | 184 | "shll %0 \n" |
186 | "shll %0 \n" | 185 | "mov %1,r0 \n" |
187 | "mov.b %3,@%4 \n" | 186 | "bt 1f \n" |
188 | 187 | "and %5,r0 \n" | |
189 | "bf 1f \n" | 188 | "1: \n" |
190 | "mov.b %1,@%4 \n" | 189 | "shll %0 \n" |
191 | "1: \n" | 190 | "mov.b r0,@%3 \n" |
192 | "or.b %2,@(r0,gbr) \n" | 191 | "or %2,r0 \n" |
193 | "shll %0 \n" | 192 | "mov.b r0,@%3 \n" |
194 | "mov.b %3,@%4 \n" | 193 | |
195 | 194 | "mov %1,r0 \n" | |
196 | "bf 1f \n" | 195 | "bt 1f \n" |
197 | "mov.b %1,@%4 \n" | 196 | "and %5,r0 \n" |
198 | "1: \n" | 197 | "1: \n" |
199 | "or.b %2,@(r0,gbr) \n" | 198 | "mov.b r0,@%3 \n" |
200 | "shll %0 \n" | 199 | "or %2,r0 \n" |
201 | "mov.b %3,@%4 \n" | 200 | "mov.b r0,@%3 \n" |
202 | 201 | ||
203 | "bf 1f \n" | 202 | "shll %0 \n" |
204 | "mov.b %1,@%4 \n" | 203 | "mov %1,r0 \n" |
205 | "1: \n" | 204 | "bt 1f \n" |
206 | "or.b %2,@(r0,gbr) \n" | 205 | "and %5,r0 \n" |
207 | "shll %0 \n" | 206 | "1: \n" |
208 | "mov.b %3,@%4 \n" | 207 | "shll %0 \n" |
209 | 208 | "mov.b r0,@%3 \n" | |
210 | "bf 1f \n" | 209 | "or %2,r0 \n" |
211 | "mov.b %1,@%4 \n" | 210 | "mov.b r0,@%3 \n" |
212 | "1: \n" | 211 | |
213 | "or.b %2,@(r0,gbr) \n" | 212 | "mov %1,r0 \n" |
214 | "shll %0 \n" | 213 | "bt 1f \n" |
215 | "mov.b %3,@%4 \n" | 214 | "and %5,r0 \n" |
216 | 215 | "1: \n" | |
217 | "bf 1f \n" | 216 | "mov.b r0,@%3 \n" |
218 | "mov.b %1,@%4 \n" /* set SD high, SC low still */ | 217 | "or %2,r0 \n" |
219 | "1: \n" | 218 | "mov.b r0,@%3 \n" |
220 | "or.b %2,@(r0,gbr) \n" /* rise SC (independent of SD level) */ | 219 | |
221 | 220 | "shll %0 \n" | |
222 | "or.b %5,@(r0,gbr) \n" /* restore port */ | 221 | "mov %1,r0 \n" |
222 | "bt 1f \n" | ||
223 | "and %5,r0 \n" | ||
224 | "1: \n" | ||
225 | "shll %0 \n" | ||
226 | "mov.b r0,@%3 \n" | ||
227 | "or %2,r0 \n" | ||
228 | "mov.b r0,@%3 \n" | ||
229 | |||
230 | "mov %1,r0 \n" | ||
231 | "bt 1f \n" | ||
232 | "and %5,r0 \n" | ||
233 | "1: \n" | ||
234 | "mov.b r0,@%3 \n" | ||
235 | "or %2,r0 \n" | ||
236 | "mov.b r0,@%3 \n" | ||
237 | |||
238 | "or %4,r0 \n" /* restore port */ | ||
239 | "mov.b r0,@%3 \n" | ||
223 | : /* outputs */ | 240 | : /* outputs */ |
224 | : /* inputs */ | 241 | : /* inputs */ |
225 | /* %0 */ "r"(byte), | 242 | /* %0 */ "r"(byte), |
226 | /* %1 */ "r"(sda1), | 243 | /* %1 */ "r"(sda1), |
227 | /* %2 */ "I"(LCD_SC), | 244 | /* %2 */ "I"(LCD_SC), |
228 | /* %3 */ "r"(clk0sda0), | 245 | /* %3 */ "r"(LCDR), |
229 | /* %4 = r0 */ "z"(LCDR), | 246 | /* %4 */ "I"(LCD_CS | LCD_DS | LCD_SD | LCD_SC), |
230 | /* %5 */ "I"(LCD_CS|LCD_DS|LCD_SD|LCD_SC) | 247 | /* %5 */ "I"(~(LCD_SD)) |
248 | : /* trashed */ | ||
249 | "r0" | ||
231 | ); | 250 | ); |
232 | 251 | ||
233 | /* This is the place to reenable the interrupts, if we have disabled | 252 | /* This is the place to reenable the interrupts, if we have disabled |
@@ -272,12 +291,13 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
272 | /* unrolled loop to serialize the byte */ | 291 | /* unrolled loop to serialize the byte */ |
273 | asm ( | 292 | asm ( |
274 | "shll %0 \n" /* shift the MSB into carry */ | 293 | "shll %0 \n" /* shift the MSB into carry */ |
294 | ".align 2 \n" | ||
275 | "negc %1, r0 \n" /* carry to SD, SC low */ | 295 | "negc %1, r0 \n" /* carry to SD, SC low */ |
296 | "shll %0 \n" /* next shift here for alignment */ | ||
276 | "mov.b r0,@%3 \n" /* set data to port */ | 297 | "mov.b r0,@%3 \n" /* set data to port */ |
277 | "or %2, r0 \n" /* rise SC (independent of SD level) */ | 298 | "or %2, r0 \n" /* rise SC (independent of SD level) */ |
278 | "mov.b r0,@%3 \n" /* set to port */ | 299 | "mov.b r0,@%3 \n" /* set to port */ |
279 | 300 | ||
280 | "shll %0 \n" | ||
281 | "negc %1, r0 \n" | 301 | "negc %1, r0 \n" |
282 | "mov.b r0,@%3 \n" | 302 | "mov.b r0,@%3 \n" |
283 | "or %2, r0 \n" | 303 | "or %2, r0 \n" |
@@ -285,11 +305,11 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
285 | 305 | ||
286 | "shll %0 \n" | 306 | "shll %0 \n" |
287 | "negc %1, r0 \n" | 307 | "negc %1, r0 \n" |
308 | "shll %0 \n" | ||
288 | "mov.b r0,@%3 \n" | 309 | "mov.b r0,@%3 \n" |
289 | "or %2, r0 \n" | 310 | "or %2, r0 \n" |
290 | "mov.b r0,@%3 \n" | 311 | "mov.b r0,@%3 \n" |
291 | 312 | ||
292 | "shll %0 \n" | ||
293 | "negc %1, r0 \n" | 313 | "negc %1, r0 \n" |
294 | "mov.b r0,@%3 \n" | 314 | "mov.b r0,@%3 \n" |
295 | "or %2, r0 \n" | 315 | "or %2, r0 \n" |
@@ -297,11 +317,11 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
297 | 317 | ||
298 | "shll %0 \n" | 318 | "shll %0 \n" |
299 | "negc %1, r0 \n" | 319 | "negc %1, r0 \n" |
320 | "shll %0 \n" | ||
300 | "mov.b r0,@%3 \n" | 321 | "mov.b r0,@%3 \n" |
301 | "or %2, r0 \n" | 322 | "or %2, r0 \n" |
302 | "mov.b r0,@%3 \n" | 323 | "mov.b r0,@%3 \n" |
303 | 324 | ||
304 | "shll %0 \n" | ||
305 | "negc %1, r0 \n" | 325 | "negc %1, r0 \n" |
306 | "mov.b r0,@%3 \n" | 326 | "mov.b r0,@%3 \n" |
307 | "or %2, r0 \n" | 327 | "or %2, r0 \n" |
@@ -309,11 +329,11 @@ void lcd_write_data(unsigned char* p_bytes, int count) | |||
309 | 329 | ||
310 | "shll %0 \n" | 330 | "shll %0 \n" |
311 | "negc %1, r0 \n" | 331 | "negc %1, r0 \n" |
332 | "shll %0 \n" | ||
312 | "mov.b r0,@%3 \n" | 333 | "mov.b r0,@%3 \n" |
313 | "or %2, r0 \n" | 334 | "or %2, r0 \n" |
314 | "mov.b r0,@%3 \n" | 335 | "mov.b r0,@%3 \n" |
315 | 336 | ||
316 | "shll %0 \n" | ||
317 | "negc %1, r0 \n" | 337 | "negc %1, r0 \n" |
318 | "mov.b r0,@%3 \n" | 338 | "mov.b r0,@%3 \n" |
319 | "or %2, r0 \n" | 339 | "or %2, r0 \n" |