| Line 90... |
Line 90... |
| 90 |
void lcd_shutdown()
|
90 |
void lcd_shutdown()
|
| 91 |
{
|
91 |
{
|
| 92 |
mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
|
92 |
mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
|
| 93 |
displaylcd_sync();
|
93 |
displaylcd_sync();
|
| 94 |
while (!(LCDSTATUS & 0x2));
|
94 |
while (!(LCDSTATUS & 0x2));
|
| 95 |
LCDCON = 0x41100db8;
|
95 |
LCDCON = 0x81100db8;
|
| 96 |
}
|
96 |
}
|
| 97 |
|
97 |
|
| 98 |
bool displaylcd_busy() ICODE_ATTR;
|
98 |
bool displaylcd_busy() ICODE_ATTR;
|
| 99 |
bool displaylcd_busy()
|
99 |
bool displaylcd_busy()
|
| 100 |
{
|
100 |
{
|
| Line 119... |
Line 119... |
| 119 |
mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
|
119 |
mutex_lock(&lcd_mutex, TIMEOUT_BLOCK);
|
| 120 |
displaylcd_sync();
|
120 |
displaylcd_sync();
|
| 121 |
}
|
121 |
}
|
| 122 |
else while (DMAC0C4CONFIG & 1);
|
122 |
else while (DMAC0C4CONFIG & 1);
|
| 123 |
while (!(LCDSTATUS & 0x2));
|
123 |
while (!(LCDSTATUS & 0x2));
|
| 124 |
LCDCON = 0x41100db8;
|
124 |
LCDCON = 0x81100db8;
|
| 125 |
lcd_send_cmd(0x2a);
|
125 |
lcd_send_cmd(0x2a);
|
| 126 |
lcd_send_data(startx);
|
126 |
lcd_send_data(startx);
|
| 127 |
lcd_send_data(endx);
|
127 |
lcd_send_data(endx);
|
| 128 |
lcd_send_cmd(0x2b);
|
128 |
lcd_send_cmd(0x2b);
|
| 129 |
lcd_send_data(starty);
|
129 |
lcd_send_data(starty);
|
| Line 188... |
Line 188... |
| 188 |
ICODE_ATTR __attribute__((naked,noinline));
|
188 |
ICODE_ATTR __attribute__((naked,noinline));
|
| 189 |
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,
|
| 190 |
unsigned int height, void* data, unsigned int datax,
|
190 |
unsigned int height, void* data, unsigned int datax,
|
| 191 |
unsigned int datay, unsigned int stride, bool solid)
|
191 |
unsigned int datay, unsigned int stride, bool solid)
|
| 192 |
{
|
192 |
{
|
| 193 |
//TODO: This is ARMv5E optimized assembly, should be converted to ARMv6
|
- |
|
| 194 |
__asm__ volatile(" muls r12, r2, r3 \n");
|
193 |
__asm__ volatile(" muls r12, r2, r3 \n");
|
| 195 |
__asm__ volatile(" bxeq lr \n");
|
194 |
__asm__ volatile(" bxeq lr \n");
|
| 196 |
__asm__ volatile(" stmfd sp!, {r1-r11,lr} \n");
|
195 |
__asm__ volatile(" stmfd sp!, {r1-r11,lr} \n");
|
| 197 |
__asm__ volatile(" mov r12, #0 \n");
|
196 |
__asm__ volatile(" mov r12, #0 \n");
|
| 198 |
__asm__ volatile(" str r12, [sp] \n");
|
197 |
__asm__ volatile(" str r12, [sp] \n");
|
| 199 |
__asm__ volatile(" mov r12, r2 \n");
|
198 |
__asm__ volatile(" mov r12, r2 \n");
|
| 200 |
__asm__ volatile(" add r8, r2, r2,lsl#1 \n");
|
199 |
__asm__ volatile(" mov r8, r2,lsl#2 \n");
|
| 201 |
__asm__ volatile(" add r3, r1, r3 \n");
|
200 |
__asm__ volatile(" add r3, r1, r3 \n");
|
| - |
|
201 |
__asm__ volatile(" add r8, r8, #4 \n");
|
| 202 |
__asm__ volatile(" sub r3, r3, #1 \n");
|
202 |
__asm__ volatile(" sub r3, r3, #1 \n");
|
| 203 |
__asm__ volatile(" mov r2, r1 \n");
|
203 |
__asm__ volatile(" mov r2, r1 \n");
|
| 204 |
__asm__ volatile(" add r1, r0, r12 \n");
|
204 |
__asm__ volatile(" add r1, r0, r12 \n");
|
| 205 |
__asm__ volatile(" sub r1, r1, #1 \n");
|
205 |
__asm__ volatile(" sub r1, r1, #1 \n");
|
| 206 |
__asm__ volatile(" bl displaylcd_setup \n");
|
206 |
__asm__ volatile(" bl displaylcd_setup \n");
|
| Line 224... |
Line 224... |
| 224 |
__asm__ volatile(" cmp r2, #0 \n");
|
224 |
__asm__ volatile(" cmp r2, #0 \n");
|
| 225 |
__asm__ volatile(" ldreq r1, [sp] \n");
|
225 |
__asm__ volatile(" ldreq r1, [sp] \n");
|
| 226 |
__asm__ volatile(" add r3, r3, r0 \n");
|
226 |
__asm__ volatile(" add r3, r3, r0 \n");
|
| 227 |
__asm__ volatile(" subeq r11, r11, r1 \n");
|
227 |
__asm__ volatile(" subeq r11, r11, r1 \n");
|
| 228 |
__asm__ volatile(" add r11, r11, r11,lsl#1 \n");
|
228 |
__asm__ volatile(" add r11, r11, r11,lsl#1 \n");
|
| 229 |
__asm__ volatile(" movne r10, #3 \n");
|
229 |
__asm__ volatile(" movne r10, #0 \n");
|
| 230 |
__asm__ volatile(" moveq r10, #0 \n");
|
230 |
__asm__ volatile(" moveq r10, #3 \n");
|
| 231 |
__asm__ volatile(" ldr r9, =0x38300040 \n");
|
231 |
__asm__ volatile(" ldr r9, =0x38300040 \n");
|
| 232 |
__asm__ volatile("displaylcd_dither_wait : \n");
|
232 |
__asm__ volatile("displaylcd_dither_wait : \n");
|
| 233 |
__asm__ volatile(" ldr r4, [r9,#-0x24] \n");
|
233 |
__asm__ volatile(" ldr r4, [r9,#-0x24] \n");
|
| 234 |
__asm__ volatile(" tst r4, #2 \n");
|
234 |
__asm__ volatile(" tst r4, #2 \n");
|
| 235 |
__asm__ volatile(" beq displaylcd_dither_wait \n");
|
235 |
__asm__ volatile(" beq displaylcd_dither_wait \n");
|
| 236 |
__asm__ volatile(" ldr r4, =0x41104eb8 \n");
|
236 |
__asm__ volatile(" ldr r4, =0x81104eb8 \n");
|
| 237 |
__asm__ volatile(" str r4, [r9,#-0x40] \n");
|
237 |
__asm__ volatile(" str r4, [r9,#-0x40] \n");
|
| - |
|
238 |
__asm__ volatile(" ldr r6, =0x30303 \n");
|
| - |
|
239 |
__asm__ volatile(" ldr r4, =0x808080 \n");
|
| 238 |
__asm__ volatile("displaylcd_dither_y: \n");
|
240 |
__asm__ volatile("displaylcd_dither_y: \n");
|
| 239 |
__asm__ volatile(" ldr lr, [sp] \n");
|
241 |
__asm__ volatile(" ldr lr, [sp] \n");
|
| 240 |
__asm__ volatile(" mov r4, #0 \n");
|
- |
|
| 241 |
__asm__ volatile(" mov r5, #0 \n");
|
242 |
__asm__ volatile(" mov r5, #0 \n");
|
| 242 |
__asm__ volatile(" mov r6, #0 \n");
|
- |
|
| 243 |
__asm__ volatile(" mov r7, r8 \n");
|
243 |
__asm__ volatile(" mov r7, r8 \n");
|
| 244 |
__asm__ volatile("displaylcd_dither_x: \n");
|
244 |
__asm__ volatile("displaylcd_dither_x: \n"); // the lcd can accept one pixel every 25 clocks
|
| 245 |
__asm__ volatile(" ldrb r1, [r3], #1 \n");
|
- |
|
| 246 |
__asm__ volatile(" ldrsb r0, [r7] \n");
|
245 |
__asm__ volatile(" ldr r0, [r3] \n"); // 1 cycle, 2 mem, r0 latency 4, r3 early
|
| 247 |
__asm__ volatile(" add r1, r1, r4 \n");
|
246 |
__asm__ volatile(" add r3, r3, r10 \n"); // 1 cycle
|
| 248 |
__asm__ volatile(" add r1, r1, r0 \n");
|
247 |
__asm__ volatile(" ldr r1, [r7,#4] \n"); // 1 cycle, 1 mem, r1 latency 3, r7 early
|
| 249 |
__asm__ volatile(" cmp r1, #0xff \n");
|
- |
|
| 250 |
__asm__ volatile(" mvnhi r1, r1,asr#31 \n");
|
- |
|
| 251 |
__asm__ volatile(" andhi r1, r1, #0xff \n");
|
- |
|
| 252 |
__asm__ volatile(" mov r0, r1,lsr#2 \n");
|
- |
|
| 253 |
__asm__ volatile(" mov r2, r0,lsl#18 \n");
|
- |
|
| 254 |
__asm__ volatile(" sub r1, r1, r0,lsl#2 \n");
|
- |
|
| 255 |
__asm__ volatile(" sub r1, r1, r0,lsr#4 \n");
|
- |
|
| 256 |
__asm__ volatile(" mov r4, r4,lsr#1 \n");
|
- |
|
| 257 |
__asm__ volatile(" add r4, r4, r1,lsr#2 \n");
|
- |
|
| 258 |
__asm__ volatile(" strb r4, [r7], #1 \n");
|
248 |
__asm__ volatile(" subs lr, lr, #1 \n"); // 1 cycle
|
| 259 |
__asm__ volatile(" mov r4, r1,asr#1 \n");
|
- |
|
| 260 |
__asm__ volatile(" ldrb r1, [r3], #1 \n");
|
- |
|
| 261 |
__asm__ volatile(" ldrsb r0, [r7] \n");
|
249 |
__asm__ volatile(" ssub8 r0, r0, r4 \n"); // 1 cycle
|
| 262 |
__asm__ volatile(" add r1, r1, r5 \n");
|
250 |
__asm__ volatile(" sadd8 r1, r1, r5 \n"); // 1 cycle
|
| 263 |
__asm__ volatile(" add r1, r1, r0 \n");
|
251 |
__asm__ volatile(" qadd8 r0, r0, r1 \n"); // 1 cycle, r0 latency 2
|
| 264 |
__asm__ volatile(" cmp r1, #0xff \n");
|
252 |
// bubble (due to r0 latency)
|
| 265 |
__asm__ volatile(" mvnhi r1, r1,asr#31 \n");
|
- |
|
| 266 |
__asm__ volatile(" andhi r1, r1, #0xff \n");
|
- |
|
| 267 |
__asm__ volatile(" mov r0, r1,lsr#2 \n");
|
253 |
__asm__ volatile(" sadd8 r0, r0, r4 \n"); // 1 cycle
|
| 268 |
__asm__ volatile(" orr r2, r2, r0,lsl#10 \n");
|
- |
|
| 269 |
__asm__ volatile(" sub r1, r1, r0,lsl#2 \n");
|
- |
|
| 270 |
__asm__ volatile(" sub r1, r1, r0,lsr#4 \n");
|
- |
|
| 271 |
__asm__ volatile(" mov r5, r5,lsr#1 \n");
|
- |
|
| 272 |
__asm__ volatile(" add r5, r5, r1,lsr#2 \n");
|
- |
|
| 273 |
__asm__ volatile(" strb r5, [r7], #1 \n");
|
254 |
__asm__ volatile(" str r0, [r9] \n"); // 1 cycle, 1 mem, r9 early
|
| 274 |
__asm__ volatile(" mov r5, r1,asr#1 \n");
|
- |
|
| 275 |
__asm__ volatile(" ldrb r1, [r3], #1 \n");
|
- |
|
| 276 |
__asm__ volatile(" ldrsb r0, [r7] \n");
|
255 |
__asm__ volatile(" bic r2, r0, r6 \n"); // 1 cycle
|
| 277 |
__asm__ volatile(" add r1, r1, r6 \n");
|
256 |
__asm__ volatile(" and r1, r6, r0,lsr#6 \n"); // 1 cycle, r0 early
|
| 278 |
__asm__ volatile(" add r1, r1, r0 \n");
|
257 |
__asm__ volatile(" orr r2, r2, r1 \n"); // 1 cycle
|
| 279 |
__asm__ volatile(" cmp r1, #0xff \n");
|
258 |
__asm__ volatile(" mov r1, r5 \n"); // 1 cycle
|
| 280 |
__asm__ volatile(" mvnhi r1, r1,asr#31 \n");
|
259 |
__asm__ volatile(" shsub8 r5, r0, r2 \n"); // 1 cycle
|
| 281 |
__asm__ volatile(" andhi r1, r1, #0xff \n");
|
260 |
__asm__ volatile(" shadd8 r1, r1, r5 \n"); // 1 cycle
|
| 282 |
__asm__ volatile(" mov r0, r1,lsr#2 \n");
|
- |
|
| 283 |
__asm__ volatile(" orr r2, r2, r0,lsl#2 \n");
|
- |
|
| 284 |
__asm__ volatile(" sub r1, r1, r0,lsl#2 \n");
|
- |
|
| 285 |
__asm__ volatile(" sub r1, r1, r0,lsr#4 \n");
|
- |
|
| 286 |
__asm__ volatile(" mov r6, r6,lsr#1 \n");
|
- |
|
| 287 |
__asm__ volatile(" add r6, r6, r1,lsr#2 \n");
|
- |
|
| 288 |
__asm__ volatile(" strb r6, [r7], #1 \n");
|
261 |
__asm__ volatile(" str r1, [r7], #4 \n"); // 1 cycle, 1 mem, r7 early
|
| 289 |
__asm__ volatile("displaylcd_dither_wait2: \n");
|
- |
|
| 290 |
__asm__ volatile(" ldr r0, [r9,#-0x24] \n");
|
- |
|
| 291 |
__asm__ volatile(" mov r6, r1,asr#1 \n");
|
- |
|
| 292 |
__asm__ volatile(" tst r0, #0x10 \n");
|
262 |
__asm__ volatile(" nop \n"); // 2 cycles
|
| 293 |
__asm__ volatile(" bne displaylcd_dither_wait2 \n");
|
- |
|
| 294 |
__asm__ volatile(" str r2, [r9] \n");
|
263 |
__asm__ volatile(" nop \n"); // 2 cycles
|
| 295 |
__asm__ volatile(" sub r3, r3, r10 \n");
|
264 |
__asm__ volatile(" nop \n"); // 2 cycles
|
| 296 |
__asm__ volatile(" subs lr, lr, #1 \n");
|
265 |
__asm__ volatile(" nop \n"); // 2 cycles
|
| 297 |
__asm__ volatile(" bne displaylcd_dither_x \n");
|
266 |
__asm__ volatile(" bne displaylcd_dither_x \n");
|
| 298 |
__asm__ volatile(" add r3, r3, r11 \n");
|
267 |
__asm__ volatile(" add r3, r3, r11 \n");
|
| 299 |
__asm__ volatile(" subs r12, r12, #1 \n");
|
268 |
__asm__ volatile(" subs r12, r12, #1 \n");
|
| 300 |
__asm__ volatile(" bne displaylcd_dither_y \n");
|
269 |
__asm__ volatile(" bne displaylcd_dither_y \n");
|
| 301 |
__asm__ volatile("displaylcd_dither_free: \n");
|
270 |
__asm__ volatile("displaylcd_dither_free: \n");
|