Hi,
please have a look to the following part I copied from the Mega32A CPU
description:
6.7.1 Interrupt Response Time
The interrupt execution response for all the enabled AVR interrupts is
four clock cycles mini-
mum. After four clock cycles the program vector address for the actual
interrupt handling routine
is executed. During this four clock cycle period, the Program Counter is
pushed onto the Stack.
The vector is normally a jump to the interrupt routine, and this jump
takes three clock cycles. If
an interrupt occurs during execution of a multi-cycle instruction, this
instruction is completed
before the interrupt is served. If an interrupt occurs when the MCU is
in sleep mode, the interrupt
execution response time is increased by four clock cycles. This increase
comes in addition to the
start-up time from the selected sleep mode.
A return from an interrupt handling routine takes four clock cycles.
During these four clock
cycles, the Program Counter (two bytes) is popped back from the Stack,
the Stack Pointer is
incremented by two, and the I-bit in SREG is set.
Also please have a look to avr-libc. If they change the SP and reload it
the sequence of assembler instructions take the delay into account.
Cheers,
Knut
Am 25.01.2013 13:21, schrieb Klaus Rudolph:
Hi Petr,
back again from my little lab:
I executed the follwing code on a atmega32 (real device on stk500 )
1 #include <avr/io.h>
2 #include <avr/interrupt.h>
3
4 #undef _SFR_IO8
5 #define _SFR_IO8(x) (x)
6 #undef _SFR_IO16
7 #define _SFR_IO16(x) (x)
8
9
10 .global main
11 main:
12 ldi r16, 0xff ; all pins output
13 out DDRB, r16 ; all pins output
14 ldi r16, 0x01 ; one pin on
15 out PORTB, r16 ; initial only 1 pin
16
17 ldi r17, 0x55
18 sei ; enable interrupts
19 ldi r16, (1<<UDRIE) ; lets generate a usart data register
empty irq
20 out UCSRB, r16 ; which should exactly now take place BUT ->
21 out PORTB, r17 ; if this instruction is executed, we
will see 0x55 on portb!
22
23 ; normaly never execute any of the following instructions, we caught
into irq handler
24 ldi r17, 0x0f; ; if irq will not be executed or comes back
25 out PORTB, r17 ; we see 0x0f on port b which should not
happen
26 ret ; this will result in going back to
ctors_end -> exit
27
28 .global USART_UDRE_vect
29 USART_UDRE_vect:
30 rjmp USART_UDRE_vect
31
32 .global stopsim
33 stopsim:
34 reti
35
The result is:
PORTB shows 0x55 pattern!
That is exactly what I expect but seems first unbelievable :-)
What we have: After raising the irq on line 20 we have one more
instruction executed which writes the port value to the 0x55 pattern.
The reason for this is not manipulating the I flag in the instruction
before. So it looks that every pending interrupt will execute a single
instruction on normal program flow before entering the irq handler.
If there is no coding error or an interpretation issue I think my patch
is exactly doing what the real device do in respect of the instruction
following the pending irq.
What I could not check is the timing behavior for the wait states of the
next instructions. Maybe it is possible to setup a timer and read back
the counter after execution or some other idea. But I think that is not
so important in the moment (for me).
I will do some more testcases on real device and on simulavr and make
unit tests for them.
Please tell me if you could find any mistakes!
Regards
Klaus
_______________________________________________
Simulavr-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/simulavr-devel
_______________________________________________
Simulavr-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/simulavr-devel