Confusion with interrupt vector tables ?!?

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In a C compiler setting appropriate vectors to point to ISR routines and their handlers is straightforward and makes sense, but when having to get dragged back (kicking and screaming) to the world off assemblers, all of a sudden, the vector tables make no sense ?!?

The defines below show the various vector jumps for all Mega32 interrupts as per datasheet. What I need to make use of is only timer0_ovf and timer2_ovf ISRs. According to data sheet this makes the position in low flash at around 0x00A for timer2, and 0x016 for timer0.

Not sure what I'm missing here, but what actually works is the assembly code below with TIM0_OVF originating at 16*4 (64), and TIM2_OVF originating at 5*4 (20).

When I check the assemled hex code (using VR Studio debugger, memory window) I see the JMP instruction at addresses for Reset at 0x000000, TIM0_OVF JMP instructions at 0x000020, and the TIM2_OVF JMP instruction at 0x00000A. This does not correspond to my expectation for those vector jumps to be according to the definitions of the tag variables.

So how are the positions of the vector JMPs calculated to correspond to what the Mega32 expects when it receives an appropriate interrupt ?? In assembly this makes a lot less sense than when using a c compiler ... any hints would be much appreciated.

INT0addr = $002	; External Interrupt0 Vector Address
INT1addr = $004	; External Interrupt1 Vector Address
INT2addr = $006	; External Interrupt2 Vector Address
OC2addr  = $008	; Output Compare2 Interrupt Vector Address
OVF2addr = $00a	; Overflow2 Interrupt Vector Address
ICP1addr = $00c	; Input Capture1 Interrupt Vector Address
OC1Aaddr = $00e	; Output Compare1A Interrupt Vector Address
OC1Baddr = $010	; Output Compare1B Interrupt Vector Address
OVF1addr = $012	; Overflow1 Interrupt Vector Address
OC0addr  = $014	; Output Compare0 Interrupt Vector Address
OVF0addr = $016	; Overflow0 Interrupt Vector Address
SPIaddr  = $018	; SPI Interrupt Vector Address
URXCaddr = $01a	; USART Receive Complete Interrupt Vector Address
UDREaddr = $01c	; USART Data Register Empty Interrupt Vector Address
UTXCaddr = $01e	; USART Transmit Complete Interrupt Vector Address
ADCCaddr = $020	; ADC Interrupt Vector Address
ERDYaddr = $022	; EEPROM Interrupt Vector Address
ACIaddr  = $024	; Analog Comparator Interrupt Vector Address
TWSIaddr = $026   ; Irq. vector address for Two-Wire Interface
SPMRaddr = $028	; Store Program Memory Ready Interrupt Vector Address


;********************************************************************************************************
;                                        INTERRUPT VECTOR TABLE
;********************************************************************************************************
;
;				 TIM0_OVF		
                 .area   OSTickISR_Vector(abs)
                 .org    16*4
                 JMP     _OSTickISR
;
;				 TIM2_OVF		
                 .area   Timer2_Vector(abs)
                 .org    5*4
                 JMP     _Timer2ISR

;                END
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

maybe it has something to do with following.
Interrupt vectors are stored in program memory (FLASH). The program memory is 16 bit wide, so each address stores 16 bit or 2 bytes.
The vector table does not store addresses, but JMP instructions. A JMP instruction is 32 bit wide (the instruction itself and the 16 bit wide address, when using ATMEGA128 there is also one address bit in the instruction itself).

So each member of the vector table contains 4 bytes. However 2 addresses because the program memory is 16 bit wide.
depending upon how your definitions are represented there are either 2 address steps or 4 byte step in between each interrupt vector.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It would help if you told what tools you are using.

The vector table in the datasheet gives the >>word<< address into the flash. All flash instructions are on a 16-bit word boundary and are 1 or more words.

Your assembler may .org to the 8-bit >>byte<< address. Thus, the .org byte address would be twice the word address. Is that your question? Check your assembler's documentation on what the .org means.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Right, Atmel be aware :) I have mentioned this to my local FAE before and they did not see it as a confusion in the way that I did :)

The vector on the devices with larger memories are shown in the datasheets as WORD addresses, and not BYTE addresses. I consider this to be very very silly. As when you want to org the address you have problem you have seen.

The mega48/88/168 datasheet is the example that explains this best, I think all datasheets should have it :)

"Each Interrupt Vector occupies two instruction words in ATmega168, and one instruction word in ATmega48 and ATmega88."

ie. rjmp version for the 48/88 and jmp for the 168.

Kanda

Kanda Embedded Tools
https://www.kanda.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the replies.

Have considered the factor of 2 in the word/byte etc., the problem is the TIM0_OVF at 0x016 (as per Mega32 data sheet). This translates to word address 22 or byte address 44. Correct ?

The debugger memory window shows me JMP instructions at 0x00000A (for TIM2_OVF) and 0x000020 (for TIM0_OVF). This later JMP is at byte addres 64 (or word address 32) ?!?! In aother words there's an offset of 20 bytes ?!? This doesn't make sense, when clearly the .org indicates 16*4 and the data sheet says clearly TIM0_OVF is at 0x0016 word address.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

alphane wrote:
Thanks for the replies.

Have considered the factor of 2 in the word/byte etc., the problem is the TIM0_OVF at 0x016 (as per Mega32 data sheet). This translates to word address 22 or byte address 44. Correct ?

The debugger memory window shows me JMP instructions at 0x00000A (for TIM2_OVF) and 0x000020 (for TIM0_OVF). This later JMP is at byte addres 64 (or word address 32) ?!?! In aother words there's an offset of 20 bytes ?!? This doesn't make sense, when clearly the .org indicates 16*4 and the data sheet says clearly TIM0_OVF is at 0x0016 word address.

OK it appears th NOPs in the code had something to do with it ... micro was just branching to a NOP instruction untill it reached the JMP instruction at word addres 0x0020. Silly actually 16*4 should have been 0x016 * 4 which translates to word addres of 22 so its actually OK. Thanks all ... :oops:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
its actually OK. Thanks all ...
Hmmm maybe you spend too much time with your Toyota RAV4.... :D

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:
Quote:
its actually OK. Thanks all ...
Hmmm maybe you spend too much time with your Toyota RAV4.... :D

I must admit I haven't been selling as many RAV4s lately ... but its because I can never spend enough time with my honey buny ... a mere lapse in concentration when I hit my head on the car ceiling ... ouch ! :o