| Line 89... |
Line 89... |
| 89 |
}
|
89 |
}
|
| 90 |
|
90 |
|
| 91 |
void displaylcd_sync() ICODE_ATTR;
|
91 |
void displaylcd_sync() ICODE_ATTR;
|
| 92 |
void displaylcd_sync()
|
92 |
void displaylcd_sync()
|
| 93 |
{
|
93 |
{
|
| 94 |
mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
|
- |
|
| 95 |
while (displaylcd_busy()) sleep(100);
|
94 |
while (displaylcd_busy()) sleep(100);
|
| 96 |
mutex_unlock(&lcd_mutex);
|
- |
|
| 97 |
}
|
95 |
}
|
| 98 |
|
96 |
|
| 99 |
void displaylcd_setup(unsigned int startx, unsigned int endx,
|
97 |
void displaylcd_setup(unsigned int startx, unsigned int endx,
|
| 100 |
unsigned int starty, unsigned int endy) ICODE_ATTR;
|
98 |
unsigned int starty, unsigned int endy) ICODE_ATTR;
|
| 101 |
void displaylcd_setup(unsigned int startx, unsigned int endx,
|
99 |
void displaylcd_setup(unsigned int startx, unsigned int endx,
|
| 102 |
unsigned int starty, unsigned int endy)
|
100 |
unsigned int starty, unsigned int endy)
|
| 103 |
{
|
101 |
{
|
| 104 |
mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
|
- |
|
| 105 |
displaylcd_sync();
|
102 |
displaylcd_sync();
|
| - |
|
103 |
mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
|
| 106 |
if (lcd_detect() == 2)
|
104 |
if (lcd_detect() == 2)
|
| 107 |
{
|
105 |
{
|
| 108 |
lcd_send_cmd(0x50);
|
106 |
lcd_send_cmd(0x50);
|
| 109 |
lcd_send_data(startx);
|
107 |
lcd_send_data(startx);
|
| 110 |
lcd_send_cmd(0x51);
|
108 |
lcd_send_cmd(0x51);
|
| Line 188... |
Line 186... |
| 188 |
mutex_unlock(&lcd_mutex);
|
186 |
mutex_unlock(&lcd_mutex);
|
| 189 |
}
|
187 |
}
|
| 190 |
|
188 |
|
| 191 |
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
|
189 |
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
|
| 192 |
unsigned int height, void* data, unsigned int datax,
|
190 |
unsigned int height, void* data, unsigned int datax,
|
| 193 |
unsigned int datay, unsigned int stride, bool solid) ICODE_ATTR;
|
191 |
unsigned int datay, unsigned int stride, bool solid)
|
| - |
|
192 |
ICODE_ATTR __attribute__((naked,noinline));
|
| 194 |
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
|
193 |
void displaylcd_dither(unsigned int x, unsigned int y, unsigned int width,
|
| 195 |
unsigned int height, void* data, unsigned int datax,
|
194 |
unsigned int height, void* data, unsigned int datax,
|
| 196 |
unsigned int datay, unsigned int stride, bool solid)
|
195 |
unsigned int datay, unsigned int stride, bool solid)
|
| 197 |
{
|
196 |
{
|
| - |
|
197 |
__asm__ volatile(" muls r12, r2, r3 \n");
|
| 198 |
int pixels = width * height;
|
198 |
__asm__ volatile(" bxeq lr \n");
|
| - |
|
199 |
__asm__ volatile(" stmfd sp!, {r2-r11,lr} \n");
|
| - |
|
200 |
__asm__ volatile(" mov r12, r2 \n");
|
| - |
|
201 |
__asm__ volatile(" add r8, r2, r2,lsl#1 \n");
|
| - |
|
202 |
__asm__ volatile(" add r3, r1, r3 \n");
|
| - |
|
203 |
__asm__ volatile(" sub r3, r3, #1 \n");
|
| - |
|
204 |
__asm__ volatile(" mov r2, r1 \n");
|
| - |
|
205 |
__asm__ volatile(" add r1, r0, r12 \n");
|
| - |
|
206 |
__asm__ volatile(" sub r1, r1, #1 \n");
|
| 199 |
if (pixels <= 0) return;
|
207 |
__asm__ volatile(" bl displaylcd_setup \n");
|
| - |
|
208 |
__asm__ volatile(" mov r0, r8 \n");
|
| 200 |
displaylcd_setup(x, x + width - 1, y, y + height - 1);
|
209 |
__asm__ volatile(" bl malloc \n");
|
| - |
|
210 |
__asm__ volatile(" cmp r0, #0 \n");
|
| 201 |
int corrsize = width * 3;
|
211 |
__asm__ volatile(" beq displaylcd_dither_unlock \n");
|
| - |
|
212 |
__asm__ volatile(" mov r2, r8 \n");
|
| - |
|
213 |
__asm__ volatile(" mov r1, #0 \n");
|
| - |
|
214 |
__asm__ volatile(" mov r8, r0 \n");
|
| - |
|
215 |
__asm__ volatile(" bl memset \n");
|
| - |
|
216 |
__asm__ volatile(" ldr r0, [sp,#0x30] \n");
|
| - |
|
217 |
__asm__ volatile(" ldr r1, [sp,#0x34] \n");
|
| - |
|
218 |
__asm__ volatile(" ldr r11, [sp,#0x38] \n");
|
| - |
|
219 |
__asm__ volatile(" ldr r3, [sp,#0x2c] \n");
|
| - |
|
220 |
__asm__ volatile(" mla r0, r1, r11, r0 \n");
|
| - |
|
221 |
__asm__ volatile(" ldr r12, [sp,#0x04] \n");
|
| - |
|
222 |
__asm__ volatile(" ldr r2, [sp,#0x3c] \n");
|
| - |
|
223 |
__asm__ volatile(" add r3, r3, r0,lsl#1 \n");
|
| - |
|
224 |
__asm__ volatile(" cmp r2, #0 \n");
|
| - |
|
225 |
__asm__ volatile(" ldreq r1, [sp] \n");
|
| - |
|
226 |
__asm__ volatile(" add r3, r3, r0 \n");
|
| - |
|
227 |
__asm__ volatile(" subeq r11, r11, r1 \n");
|
| 202 |
signed char* corr = (signed char*)malloc(corrsize);
|
228 |
__asm__ volatile(" add r11, r11, r11,lsl#1 \n");
|
| - |
|
229 |
__asm__ volatile(" movne r10, #3 \n");
|
| - |
|
230 |
__asm__ volatile(" moveq r10, #0 \n");
|
| - |
|
231 |
__asm__ volatile(" ldr r9, =0x38600040 \n");
|
| - |
|
232 |
__asm__ volatile("displaylcd_dither_y: \n");
|
| - |
|
233 |
__asm__ volatile(" ldr lr, [sp] \n");
|
| - |
|
234 |
__asm__ volatile(" mov r4, #0 \n");
|
| - |
|
235 |
__asm__ volatile(" mov r5, #0 \n");
|
| - |
|
236 |
__asm__ volatile(" mov r6, #0 \n");
|
| 203 |
if (!corr)
|
237 |
__asm__ volatile(" mov r7, r8 \n");
|
| 204 |
{
|
- |
|
| 205 |
mutex_unlock(&lcd_mutex);
|
238 |
__asm__ volatile("displaylcd_dither_x: \n");
|
| - |
|
239 |
__asm__ volatile(" mov r2, #0 \n");
|
| 206 |
return;
|
240 |
__asm__ volatile(" ldrb r1, [r3], #1 \n");
|
| 207 |
}
|
- |
|
| - |
|
241 |
__asm__ volatile(" ldrsb r0, [r7] \n");
|
| - |
|
242 |
__asm__ volatile(" add r1, r1, r4 \n");
|
| - |
|
243 |
__asm__ volatile(" add r1, r1, r0 \n");
|
| - |
|
244 |
__asm__ volatile(" cmp r1, #0 \n");
|
| - |
|
245 |
__asm__ volatile(" movlt r1, #0 \n");
|
| - |
|
246 |
__asm__ volatile(" cmp r1, #0xff \n");
|
| - |
|
247 |
__asm__ volatile(" movgt r1, #0xff \n");
|
| - |
|
248 |
__asm__ volatile(" mov r0, r1,lsr#3 \n");
|
| 208 |
memset(corr, 0, corrsize);
|
249 |
__asm__ volatile(" orr r2, r0,lsl#11 \n");
|
| - |
|
250 |
__asm__ volatile(" sub r1, r1, r0,lsl#3 \n");
|
| 209 |
unsigned char* in = (unsigned char*)data + (stride * datay + datax) * 3;
|
251 |
__asm__ volatile(" sub r1, r1, r0,lsr#2 \n");
|
| 210 |
for (y = 0; y < height; y++)
|
252 |
__asm__ volatile(" mov r4, r4,lsr#1 \n");
|
| 211 |
{
|
- |
|
| - |
|
253 |
__asm__ volatile(" add r4, r4, r1,lsr#2 \n");
|
| 212 |
int i;
|
254 |
__asm__ volatile(" strb r4, [r7], #1 \n");
|
| 213 |
signed char* corrptr = corr;
|
255 |
__asm__ volatile(" mov r4, r1,asr#1 \n");
|
| - |
|
256 |
__asm__ volatile(" ldrb r1, [r3], #1 \n");
|
| 214 |
signed char lastcorr[3] = {0};
|
257 |
__asm__ volatile(" ldrsb r0, [r7] \n");
|
| 215 |
for (x = 0; x < width; x++)
|
258 |
__asm__ volatile(" add r1, r1, r5 \n");
|
| 216 |
{
|
259 |
__asm__ volatile(" add r1, r1, r0 \n");
|
| 217 |
unsigned int pixel = 0;
|
260 |
__asm__ volatile(" cmp r1, #0 \n");
|
| - |
|
261 |
__asm__ volatile(" movlt r1, #0 \n");
|
| 218 |
signed char* lastcorrptr = lastcorr;
|
262 |
__asm__ volatile(" cmp r1, #0xff \n");
|
| - |
|
263 |
__asm__ volatile(" movgt r1, #0xff \n");
|
| 219 |
int orig = *in++ + *corrptr + *lastcorrptr;
|
264 |
__asm__ volatile(" mov r0, r1,lsr#2 \n");
|
| 220 |
orig = MAX(0, MIN(255, orig));
|
265 |
__asm__ volatile(" orr r2, r0,lsl#5 \n");
|
| 221 |
unsigned int real = orig >> 3;
|
266 |
__asm__ volatile(" sub r1, r1, r0,lsl#2 \n");
|
| 222 |
pixel |= real << 11;
|
267 |
__asm__ volatile(" sub r1, r1, r0,lsr#4 \n");
|
| 223 |
int err = orig - ((real << 3) | (real >> 2));
|
268 |
__asm__ volatile(" mov r5, r5,lsr#1 \n");
|
| - |
|
269 |
__asm__ volatile(" add r5, r5, r1,lsr#2 \n");
|
| 224 |
*corrptr++ = (*lastcorrptr >> 1) + err >> 2;
|
270 |
__asm__ volatile(" strb r5, [r7], #1 \n");
|
| 225 |
*lastcorrptr++ = err >> 1;
|
271 |
__asm__ volatile(" mov r5, r1,asr#1 \n");
|
| 226 |
orig = *in++ + *corrptr + *lastcorrptr;
|
272 |
__asm__ volatile(" ldrb r1, [r3], #1 \n");
|
| 227 |
orig = MAX(0, MIN(255, orig));
|
273 |
__asm__ volatile(" ldrsb r0, [r7] \n");
|
| - |
|
274 |
__asm__ volatile(" add r1, r1, r6 \n");
|
| 228 |
real = orig >> 2;
|
275 |
__asm__ volatile(" add r1, r1, r0 \n");
|
| - |
|
276 |
__asm__ volatile(" cmp r1, #0 \n");
|
| - |
|
277 |
__asm__ volatile(" movlt r1, #0 \n");
|
| - |
|
278 |
__asm__ volatile(" cmp r1, #0xff \n");
|
| 229 |
pixel |= real << 5;
|
279 |
__asm__ volatile(" movgt r1, #0xff \n");
|
| - |
|
280 |
__asm__ volatile(" mov r0, r1,lsr#3 \n");
|
| 230 |
err = orig - ((real << 2) | (real >> 4));
|
281 |
__asm__ volatile(" orr r2, r0 \n");
|
| - |
|
282 |
__asm__ volatile(" sub r1, r1, r0,lsl#3 \n");
|
| - |
|
283 |
__asm__ volatile(" sub r1, r1, r0,lsr#2 \n");
|
| 231 |
*corrptr++ = (*lastcorrptr >> 1) + err >> 2;
|
284 |
__asm__ volatile(" mov r6, r6,lsr#1 \n");
|
| 232 |
*lastcorrptr++ = err >> 1;
|
285 |
__asm__ volatile(" add r6, r6, r1,lsr#2 \n");
|
| 233 |
orig = *in++ + *corrptr + *lastcorrptr;
|
286 |
__asm__ volatile(" strb r6, [r7], #1 \n");
|
| - |
|
287 |
__asm__ volatile("displaylcd_dither_waitlcd: \n");
|
| 234 |
orig = MAX(0, MIN(255, orig));
|
288 |
__asm__ volatile(" ldr r0, [r9,#-0x24] \n");
|
| 235 |
real = orig >> 3;
|
289 |
__asm__ volatile(" mov r6, r1,asr#1 \n");
|
| - |
|
290 |
__asm__ volatile(" tst r0, #0x10 \n");
|
| 236 |
pixel |= real;
|
291 |
__asm__ volatile(" bne displaylcd_dither_waitlcd\n");
|
| - |
|
292 |
__asm__ volatile(" str r2, [r9] \n");
|
| 237 |
err = orig - ((real << 3) | (real >> 2));
|
293 |
__asm__ volatile(" sub r3, r3, r10 \n");
|
| 238 |
*corrptr++ = (*lastcorrptr >> 1) + err >> 2;
|
294 |
__asm__ volatile(" subs lr, lr, #1 \n");
|
| 239 |
*lastcorrptr++ = err >> 1;
|
295 |
__asm__ volatile(" bne displaylcd_dither_x \n");
|
| - |
|
296 |
__asm__ volatile(" add r3, r3, r11 \n");
|
| 240 |
LCDWDATA = pixel;
|
297 |
__asm__ volatile(" subs r12, r12, #1 \n");
|
| 241 |
if (solid) in -= 3;
|
298 |
__asm__ volatile(" bne displaylcd_dither_y \n");
|
| 242 |
}
|
299 |
__asm__ volatile("displaylcd_dither_free: \n");
|
| 243 |
if (solid) in += stride * 3;
|
300 |
__asm__ volatile(" mov r0, r8 \n");
|
| 244 |
else in += (stride - width) * 3;
|
301 |
__asm__ volatile(" bl free \n");
|
| 245 |
}
|
- |
|
| 246 |
free(corr);
|
302 |
__asm__ volatile("displaylcd_dither_unlock: \n");
|
| 247 |
mutex_unlock(&lcd_mutex);
|
303 |
__asm__ volatile(" ldr r0, =lcd_mutex \n");
|
| - |
|
304 |
__asm__ volatile(" bl mutex_unlock \n");
|
| - |
|
305 |
__asm__ volatile(" ldmfd sp!, {r2-r11,pc} \n");
|
| 248 |
}
|
306 |
}
|
| 249 |
|
307 |
|
| 250 |
void displaylcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height,
|
308 |
void displaylcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height,
|
| 251 |
void* data, unsigned int datax, unsigned int datay, unsigned int stride)
|
309 |
void* data, unsigned int datax, unsigned int datay, unsigned int stride)
|
| 252 |
{
|
310 |
{
|
| Line 254... |
Line 312... |
| 254 |
}
|
312 |
}
|
| 255 |
|
313 |
|
| 256 |
void filllcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int color)
|
314 |
void filllcd(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int color)
|
| 257 |
{
|
315 |
{
|
| 258 |
if (width * height <= 0) return;
|
316 |
if (width * height <= 0) return;
|
| - |
|
317 |
displaylcd_sync();
|
| 259 |
mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
|
318 |
mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
|
| 260 |
displaylcd_dither(x, y, width, height, &color, 0, 0, 0, true);
|
319 |
displaylcd_dither(x, y, width, height, &color, 0, 0, 0, true);
|
| 261 |
mutex_unlock(&lcd_mutex);
|
320 |
mutex_unlock(&lcd_mutex);
|
| 262 |
}
|
321 |
}
|
| 263 |
|
322 |
|