XINT0 - AVR simulator behaves unexpected / unpredictable

Viewed 43

In my ATTiny13 application, ExtInt0 did not respond as expected, so I started debugging (simulator in AVR Studio7, no stimuli file). To reduce complexity, I stripped my code to the absolute minimum.

; TstExtInt0.asm
;

.include "tn13def.inc"

;------------------------------------------------------
;register definitions
;------------------------------------------------------
.def    StatReg =   r2
.def    TmpReg  =   r16
.def    WaitReg1 = r20
.def    WaitReg2 = r21
.def    Flags_Reg =   r23

;------------------------------------------------------
;constants
;------------------------------------------------------
.equ    _KEY_FLAG_BIT0    =   0

;------------------------------------------------------
;interrupt vectors
;------------------------------------------------------
.org    0x0000  rjmp RESET                ;Reset
.org    0x0001  rjmp KeyPressed           ;ISR detecting button being pushed
.org    0x0002  reti; rjmp PCHINT               ;ISR Pin Change Interrupts
.org    0x0003  reti; TIM0_OVF             ;Timer0 Overflow Interrupt
;------------------------------------------------------
;Main programme - Init
;------------------------------------------------------
RESET:  ldi     TmpReg, RAMEND            ;Stack
        out     SPL, TmpReg

        ;----------------------------------------------
        ;prepare port B
        ;----------------------------------------------
        ldi        TmpReg, (1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5)
        out        ddrb, TmpReg             ;set PortB bit 0 as input, PortB bit 1 to 5 as output
        ldi        TmpReg, (1<<PB1)|(1<<PB2);set 'Enable' 
        out        PortB,TmpReg             ;and transfer to the output pins


;----------------------------------------------
;ExtInt0 init
;----------------------------------------------
        ldi         TmpReg,0x40                 ; enable ExtInt0 
        out         GIMSK,TmpReg

        sei                                     ; enable interrupts

; Initialise register values
;       ldi         T0Cycles, 0             ; reset
        ldi         Flags_Reg, 0            ; reset 

;------------------------------------------------------
; Main loop
;------------------------------------------------------
IdleKey:
        ldi     TmpReg, 0x07     ;just LEDs as indicator
        out     PortB, TmpReg
        ldi     TmpReg, 0x19
        out     PortB, TmpReg
        sbrs    Flags_Reg, _KEY_FLAG_BIT0   ; idle here as long as key not pressed / flag not set, 
; _KEY_FLAG_BIT0 in FlagsReg is set by ISR KeyPressed (Ext Int0)
        rjmp    IdleKey                     ; otherwise, key has been pressed 

idlePB0: sbis  PinB,0                       ; keep checking if PortB0 is still low, idle if necessary until level is high again
        rjmp    idlePB0                     ; otherwise
        ldi     Flags_Reg, 0                ; reset Flags_Reg again

        rjmp   IdleKey
;------------------------------------------------------
;end main loop
;------------------------------------------------------

;------------------------------------------------------
;ExtInt0 Interrupt: key is pressed
;------------------------------------------------------
KeyPressed:
        cli                         ; disable all interrupts
        in      StatReg,SREG        ; save status register
        ldi     TmpReg, 0x00
        out     GIMSK, TmpReg       ; in particular disable INT0 - for the moment don't detect further pulses (debouncing)
        ori     Flags_Reg, 0x01     ; set flag for key pressed
        out     SREG,StatReg        ; reload status register
        reti

When running the simulator, I observe the following behaviour: stepping through the code instruction by instruction, XINT0 / ISR KeyPressed never is activated (as expected when not manipulating PB.0). However, re-running the simulator on his own ('continue' button), 7 or 8 cycles later I end up at the breakpoint at the start of my ISR 'KeyPressed' (regardless at which cycle counter / instruction I continued).

To make things more confusing: I have an old laptop with AVR Studio4 running. Here, the simulator consistently jumps the first time he arrives at the line

rjmp IdleKey ; otherwise, key has been pressed

to the .org 0x0001 statement, and, hence, to the ISR.

In none of both environments, the simulator shows the ExtInt Flag in register GIFR being set, though.

Is this a bug in the simulator or is there something I do not understand regarding interrupt handling or usage of the simulator? - Thanks for your support!!

1 Answers

There are two issues present. One in confusion on whether or not an interrupt should be firing, and one in Atmel Studio settings.


The statement "as expected when not manipulating PB.0" when referring to the external interrupt INT0 is incorrect. The INT0 pin is PB1 which you have as an output which is sometimes set high in your code. Your assumption seems to be that INT0 exists on PB0.


Not having interrupts fire during stepping is an intentional feature in Atmel Studio 7 (and possibly other versions), allowing for code to be debugged without presumably arbitrarily-timed external interrupts messing with the flow of the code.

This can be disabled in Tools -> Options -> Tools -> Tool settings -> Mask interrupts while stepping.

This seems to either not be a feature, or not be enabled by default, in Atmel Studio 4, which is why you see it process the exception when expected.

Related