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.
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.
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..
rjmp INT0_Fin ; If it's the last edge, handle appropriately.
reti ; wait for next edge.
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.
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
address@hiddenwww.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.
****************************************************************************