:) Interrupt latency.
I have an app on a Mega32L, running at 4 MHz. I'm trying to measure the widths of pulses that could be as short as 5uS. The theory was to detect the first rising edge, and zero T1. Then on the second rising edge, grab the count from T1, which is running at CK/1 The problem I'm running into is that the generated ISR is showing a latency of >7uS between the high edge of the pulse that generates INT0 and where my code starts executing. Even taking the part to 8 MHZ doesn't look like it will work, yet I know that at 4 MHz I can do this job in asm. I understand what the compiler is doing, but the ISR it generates is way too slow. (see below) If I were writing this app in assembler, I'd have reserved at least two high registers for ISR use, and another low one to store SREG in, and a low register dedicated to holding 0x00, and a register holding speed-critical bit flags like Raw_Edge_Flag, so I'd have something like this: INT0: ;Same latency to this point in ASM or C.. in STEMP,SREG ; Nothing needs be pushed btss Flags,0 ; See wether this is the first or last edge rjmp INT0_Fin ; If it's the last edge, handle appropriately. out TCNT1H,ZERO ;Clear the timer out TCNT1L,ZERO ; reti ; wait for next edge. INT0_Fin: in ITEMP,TCNT1H ;Once I've captured the timer value, in ITEMP2,TCNT1L ; I don't care how long the ISR takes to run. (rest of the int for the back edge) ;since the pulse is over now. reti So my question is, how close can I get to my ASM approach, using C? 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 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 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 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 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 +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 -- David VanHorn Hardware Engineer MobileFusion, Inc 2715 Sarah St Pittsburgh PA, 15203 Phone: (001) 412-481-1111 Cell: (001) 765-215-8521 Fax: (001) 412-481-0220 d...@mobilefusioninc.com www.mobilefusioninc.com **************************************************************************** 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. ****************************************************************************
_______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list