hallo,
ich arbeite gerade an meinem ersten arm projekt, ich versuche mit dem
olimex AT91SAM7X256 + TFT+ Ethernet (SAM7-EX256) board über ein vga
interface einen monitor anzusteuern....
das ganze funktioniert auch, jedoch hab ich probleme mit der zeit bis
der erste pixel gesetzt wird.
Das hsync signal mit dem jeder neue zeilenbeginn signalisiert wird, wird
durch ein pwm signal generiert. d.h.: ich bin in der funktion draw() und
warte bis ein neuer zeilenbeginn durch den pwm interrupt
signalisiert wird, die funktion draw() wartet bis das draw_flag gesetzt
worden ist um dann mit der pixel-ausgabe zu beginnen.
die pixelausgabe erfolgt durch das setzen von portpins, das problem ist
das die zeit zwischen dem interrupt und der ausgabe des ersten pixels
variiert, somit erhalte ich keine schönen geraden balken am monitor
sondern balken mit zacken...siehe Bild
jetzt wollte ich euch fragen wie kann ich das verhindern das die zeit
vom interrupt bis zum setzen der portpins nicht variiert?
hier ist einmal der interruptrequest handler in der startup datei
1 | /* ======================================================================== */
|
2 | AT91F_Irq_Handler:
|
3 |
|
4 | /* Manage Exception Entry */
|
5 | /* Adjust and save LR_irq in IRQ stack */
|
6 | sub lr, lr, #4
|
7 | stmfd sp!, {lr}
|
8 |
|
9 | /* Save r0 and SPSR (need to be saved for nested interrupt) */
|
10 | mrs r14, SPSR
|
11 | stmfd sp!, {r0,r14}
|
12 |
|
13 | /* Write in the IVR to support Protect Mode */
|
14 | /* No effect in Normal Mode */
|
15 | /* De-assert the NIRQ and clear the source in Protect Mode */
|
16 | ldr r14, =AT91C_BASE_AIC
|
17 | ldr r0 , [r14, #AIC_IVR]
|
18 | str r14, [r14, #AIC_IVR]
|
19 |
|
20 | /* Enable Interrupt and Switch in Supervisor Mode */
|
21 | msr CPSR_c, #ARM_MODE_SVC
|
22 |
|
23 | /* Save scratch/used registers and LR in User Stack */
|
24 | stmfd sp!, { r1-r3, r12, r14}
|
25 |
|
26 | /* Branch to the routine pointed by the AIC_IVR */
|
27 | mov r14, pc
|
28 | bx r0
|
29 |
|
30 | /* Manage Exception Exit */
|
31 | /* Restore scratch/used registers and LR from User Stack */
|
32 | ldmia sp!, { r1-r3, r12, r14}
|
33 |
|
34 | /* Disable Interrupt and switch back in IRQ mode */
|
35 | msr CPSR_c, #I_BIT | ARM_MODE_IRQ
|
36 |
|
37 | /* Mark the End of Interrupt on the AIC */
|
38 | ldr r14, =AT91C_BASE_AIC
|
39 | str r14, [r14, #AIC_EOICR]
|
40 |
|
41 | /* Restore SPSR_irq and r0 from IRQ stack */
|
42 | ldmia sp!, {r0,r14}
|
43 | msr SPSR_cxsf, r14
|
44 |
|
45 | /* Restore adjusted LR_irq from IRQ stack directly in the PC */
|
46 | ldmia sp!, {pc}^
|
hier die pwm Interrupt routine...
1 | void ISR_PWM(void){
|
2 |
|
3 | draw_flag = 1;
|
4 | //acknowledge interrupt
|
5 | if ((AT91C_BASE_PWMC->PWMC_ISR & AT91C_PWMC_CHID2) == AT91C_PWMC_CHID2){
|
6 | }
|
7 | }
|
und hier die funktion draw()
1 | void draw(void){
|
2 |
|
3 | unsigned int pix_count;
|
4 | unsigned int delay;
|
5 |
|
6 | while(1){
|
7 |
|
8 | while(draw_flag != 1);
|
9 |
|
10 | for(pix_count=0;pix_count<13;pix_count++){ //38
|
11 | __asm__ __volatile__( "NOP" );
|
12 | }
|
13 |
|
14 | for(pix_count=0;pix_count<8;pix_count++){
|
15 | for(delay=0;delay<2;delay++){
|
16 | pPIO_B->PIO_ODSR = 0x78840000;
|
17 | }
|
18 | for(delay=0;delay<2;delay++){
|
19 | pPIO_B->PIO_ODSR = 0x00000000;
|
20 | }
|
21 |
|
22 | }
|
23 | draw_flag = 0;
|
24 |
|
25 | }
|
26 |
|
27 | //line_count++;
|
28 | }
|
wäre echt cool wenn jemand ne idee hätte was man da tun kann