> -----Original Message----- > From: > avr-gcc-list-bounces+eweddington=cso.atmel....@nongnu.org > [mailto:avr-gcc-list-bounces+eweddington=cso.atmel....@nongnu. > org] On Behalf Of David VanHorn > Sent: Wednesday, February 25, 2009 9:05 AM > To: avr-gcc-list@nongnu.org > Subject: [avr-gcc-list] Newbie question > > > :) > > Interrupt latency. > > So my question is, how close can I get to my ASM approach, using C?
You'll probably have to whittle this down in steps. See comments below. > > 0000022D: 9508 RET Subroutine return > @0000022E: __vector_1 > 450: { > +0000022E: 921F PUSH R1 Push > register on stack > +0000022F: 920F PUSH R0 Push > register on stack > +00000230: B60F IN R0,0x3F In from I/O location > +00000231: 920F PUSH R0 Push > register on stack > +00000232: 2411 CLR R1 Clear Register > +00000233: 938F PUSH R24 Push > register on stack > +00000234: 939F PUSH R25 Push > register on stack > +00000235: 93EF PUSH R30 Push > register on stack > +00000236: 93FF PUSH R31 Push > register on stack > 451: if (Raw_Edge_Flag == 0) // If this is the first time thru > +00000237: 91800082 LDS R24,0x0082 Load direct > from data space > +00000239: 2388 TST R24 Test for > Zero or Minus > +0000023A: F441 BRNE PC+0x09 Branch if not equal > 453: TCNT1H=0; // Timer starts at 0 > +0000023B: BD8D OUT 0x2D,R24 Out to I/O location > 454: TCNT1L=0; > +0000023C: BD8C OUT 0x2C,R24 Out to I/O location > 455: Raw_Edge_Flag = 0xFF; // Next time is the end of a pulse > +0000023D: EF8F SER R24 Set Register > +0000023E: 93800082 STS 0x0082,R24 Store > direct to data space > 456: Debug_DDR |= (1 << Debug_Pin); // Output > +00000240: 9A8D SBI 0x11,5 Set bit in > I/O register > 457: Debug_Port |= (1 << Debug_Pin); // High > +00000241: 9A95 SBI 0x12,5 Set bit in > I/O register I know that it's not adding much code, but can you remove (comment out) your debug statements, like above? I noticed there are more below, too. > 458: return; > +00000242: C020 RJMP PC+0x0021 Relative jump > 462: Raw_Data[0][Raw_Data_In_Index] = TCNT1; > +00000243: 91800083 LDS R24,0x0083 Load direct > from data space > +00000245: 2FE8 MOV R30,R24 Copy register > +00000246: 27FF CLR R31 Clear Register > +00000247: 0FEE LSL R30 Logical Shift Left > +00000248: 1FFF ROL R31 Rotate Left > Through Carry > +00000249: 57EC SUBI R30,0x7C Subtract immediate > +0000024A: 4FFF SBCI R31,0xFF Subtract > immediate with carry > +0000024B: B58C IN R24,0x2C In from I/O location > +0000024C: B59D IN R25,0x2D In from I/O location > +0000024D: 8391 STD Z+1,R25 Store > indirect with displacement > +0000024E: 8380 STD Z+0,R24 Store > indirect with displacement Your assignment into an array seems to generate a lot of code. Is there any way that you can just use some dedicated global variables while in the ISR, and then stuff values to an array during a task in the main loop? > 463: Debug_DDR |= (1 << Debug_Pin); // Output > +0000024F: 9A8D SBI 0x11,5 Set bit in > I/O register > 464: Debug_Port &=~(1 << Debug_Pin); // Low > +00000250: 9895 CBI 0x12,5 Clear bit > in I/O register More debug statements. > 465: Raw_Edge_Flag = 0; // So the next event will be > a beginning > +00000251: 92100082 STS 0x0082,R1 Store > direct to data space > 467: if ((TIFR & (1<< TOV1))==1) // If we rolled T0 > +00000253: B788 IN R24,0x38 In from I/O location > +00000254: 2799 CLR R25 Clear Register > +00000255: 7084 ANDI R24,0x04 Logical AND > with immediate > +00000256: 7090 ANDI R25,0x00 Logical AND > with immediate > +00000257: 9701 SBIW R24,0x01 Subtract > immediate from word > +00000258: F421 BRNE PC+0x05 Branch if not equal Hmm. It seems the compiler is treating this expression as a 16-bit value. It could be because of the comparison with the constant '1', which gets automatically treated like an int. Can you see if typecasting will help?: if ((TIFR & (uint8_t)(1<<TOV1)) == (uint8_t)1) If it works, it should save 2 instructions. > 470: TIFR |= (1<<TOV1); // reset the overflow condition > +00000259: B788 IN R24,0x38 In from I/O location > +0000025A: 6084 ORI R24,0x04 Logical OR > with immediate > +0000025B: BF88 OUT 0x38,R24 Out to I/O location > +0000025C: C006 RJMP PC+0x0007 Relative jump > 477: GICR |= (1 << INT1); // Enable INT1 > +0000025D: B78B IN R24,0x3B In from I/O location > +0000025E: 6880 ORI R24,0x80 Logical OR > with immediate > +0000025F: BF8B OUT 0x3B,R24 Out to I/O location > 478: GICR &=~(1 << INT0); // Disable INT0 > +00000260: B78B IN R24,0x3B In from I/O location > +00000261: 7B8F ANDI R24,0xBF Logical AND > with immediate > +00000262: BF8B OUT 0x3B,R24 Out to I/O location You're doing two assignments back to back to GICR, which causes two separate read-modify-write blocks. Is there any way that they can be combined into one step? Like so: GICR = ((GICR & ~(1<<INT0)) | (1 << INT1)); I would think this would compile to an IN,ANDI,ORI,OUT sequence > +00000263: 91FF POP R31 Pop > register from stack > +00000264: 91EF POP R30 Pop > register from stack > +00000265: 919F POP R25 Pop > register from stack > +00000266: 918F POP R24 Pop > register from stack > +00000267: 900F POP R0 Pop > register from stack > +00000268: BE0F OUT 0x3F,R0 Out to I/O location > +00000269: 900F POP R0 Pop > register from stack > +0000026A: 901F POP R1 Pop > register from stack > +0000026B: 9518 RETI > If we can keep the ISR from using as many other registers as possible, then it will help in both the ISR prologue and epilogue. > ************************************************************** > ************** > This communication (including any attachments) is for the use of the > intended recipient(s) only and may contain information that is > confidential, privileged or otherwise legally protected. Any > unauthorized use or dissemination of this communication is > prohibited. If you have received this communication in error, please > immediately notify the sender by return e-mail message and delete > all copies of the original communication. Thank you for your > cooperation. > ************************************************************** Any way that you can remove the above confidential notice? You're sending this mail to a public mailing list. Eric Weddington _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list