Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12600 Discussions

hardwere interrupt in assembly language

Altera_Forum
Honored Contributor II
1,382 Views

I can't find how to setup these external interupts I alredy tryed several codes one was from this link http://instruct1.cit.cornell.edu/courses/e..._asm/index.html (http://instruct1.cit.cornell.edu/courses/ece576/niosii_asm/index.html

and ather is form Lab exercises 4 polling an interrupts  

.include “nios macros.s” .text .org 0x20 /* Place the interrupt service routine */               /* at the appropriate address */ ISR:   rdctl et, ctl4 /* Check if an external */   beq et, r0, SKIP EA DEC /* interrupt has occurred */   subi ea, ea, 4 /* If yes, decrement ea to execute */                       /* interrupted instruction */ SKIP EA DEC: ... the interrupt-service routine END ISR:    eret /* Return from exception */ .global start start: /* Program start location */ ... enable interrupts code ... the main program code LOOP: br LOOP /* Endless loop */ .end 

 

so How to place this inteupt serivece routine after .org 0x20 ?? 

I tried in several ways like: 

.org 0x20 

jmp ISR 

 

and other was 

 

.org 0x20 

br ISR 

 

 

They didn't worked I get lot of errors by altera debug client compiler.  

ANd how to write this interupt vecotr addres? Is it somthing like offset addres for example second interupt would be .org 0x21 is it corect ??  

 

I previously coded Atmel AVR mikrocontrollers and know how to code interrupts there, but can't get in to nios II interupt assembly code. 

 

maby someone can put complete simple interupt example using PIO, or timer core http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/rolleyes.gif
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
464 Views

Hi Epis, 

 

> How to place this inteupt serivece routine after .org 0x20 ? 

 

There are several techniques you can use. I&#39;m assuming that you&#39;re not using the HAL. 

 

One technique is to place your startup code at the beginning of your application, and 

place the exception handler entry point at offset 0x20 from the start. This is the technique 

used by u-boot. For example, the file cpu/nios2/start.S: 

<div class='quotetop'>QUOTE </div> 

--- Quote Start ---  

.text 

.global _start 

 

_start: 

    /* ICACHE INIT -- only the icache line at the reset address 

    * is invalidated at reset. So the init must stay within 

    * the cache line size (8 words). If GERMS is used, we&#39;ll 

    * just be invalidating the cache a second time. If cache 

    * is not implemented initi behaves as nop. 

    */ 

    ori r4, r0, %lo(CFG_ICACHELINE_SIZE) 

    movhi r5, %hi(CFG_ICACHE_SIZE) 

    ori r5, r5, %lo(CFG_ICACHE_SIZE) 

    mov r6, r0 

0: initi r6 

    add r6, r6, r4 

    bltu r6, r5, 0b 

    br _except_end /* Skip the tramp */ 

 

    /* EXCEPTION TRAMPOLINE -- the following gets copied 

    * to the exception address (below), but is otherwise at the 

    * default exception vector offset (0x0020). 

    */ 

    . = _start + 0x20  

_except_start: 

    movhi et, %hi(_exception) 

    ori et, et, %lo(_exception) 

    jmp et 

_except_end:[/b] 

--- Quote End ---  

 

 

Your linker script must account for this by specifying the specific object module first: 

<div class='quotetop'>QUOTE </div> 

--- Quote Start ---  

SECTIONS 

.text : 

  cpu/nios2/start.o (.text) 

  *(.text) 

  *(.text.*) 

  *(.gnu.linkonce.t*) 

  *(.rodata) 

  *(.rodata.*) 

  *(.gnu.linkonce.r*) 

}[/b] 

--- Quote End ---  

 

 

This is convenient if you need to relocate the exception entry point (and other sections at 

run time) -- i.e. moving the code from flash to SDRAM without regard to the current 

location: 

<div class='quotetop'>QUOTE </div> 

--- Quote Start ---  

    /* RELOCATE CODE, DATA & COMMAND TABLE -- the following code 

    * assumes code, data and the command table are all 

    * contiguous. This lets us relocate everything as a single 

    * block. Make sure the linker script matches this ;-) 

    */ 

    nextpc r4 

_cur: movhi r5, %hi(_cur - _start) 

    ori r5, r5, %lo(_cur - _start) 

    sub r4, r4, r5  /* r4 <- cur _start */ 

    mov r8, r4 

    movhi r5, %hi(_start) 

    ori r5, r5, %lo(_start) /* r5 <- linked _start */ 

    beq r4, r5, 3f 

 

    movhi r6, %hi(_edata) 

    ori r6, r6, %lo(_edata) 

2: ldwio r7, 0(r4) 

    addi r4, r4, 4 

    stwio r7, 0(r5) 

    addi r5, r5, 4 

    bne r5, r6, 2b 

3: 

 

    /* ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent 

    * and between __bss_start and _end. 

    */ 

    movhi r5, %hi(__bss_start) 

    ori r5, r5, %lo(__bss_start) 

    movhi r6, %hi(_end) 

    ori r6, r6, %lo(_end) 

    beq r5, r6, 5f 

 

4: stwio r0, 0(r5) 

    addi r5, r5, 4 

    bne r5, r6, 4b 

5: 

 

    /* GLOBAL POINTER -- the global pointer is used to reference 

    * "small data" (see -G switch). The linker script must 

    * provide the gp address. 

    */ 

    movhi gp, %hi(_gp) 

    ori gp, gp, %lo(_gp) 

 

    /* JUMP TO RELOC ADDR */ 

    movhi r4, %hi(_reloc) 

    ori r4, r4, %lo(_reloc) 

    jmp r4 

_reloc: 

 

    /* COPY EXCEPTION TRAMPOLINE -- copy the tramp to the 

    * exception address. Define CONFIG_ROM_STUBS to prevent 

    * the copy (e.g. exception in flash or in other 

    * softare/firmware component). 

    */ 

    movhi r4, %hi(_except_start) 

    ori r4, r4, %lo(_except_start) 

    movhi r5, %hi(_except_end) 

    ori r5, r5, %lo(_except_end) 

    movhi r6, %hi(CFG_EXCEPTION_ADDR) 

    ori r6, r6, %lo(CFG_EXCEPTION_ADDR) 

    beq r4, r6, 7f /* Skip if at proper addr */ 

 

6: ldwio r7, 0(r4) 

    stwio r7, 0(r6) 

    addi r4, r4, 4 

    addi r6, r6, 4 

    bne r4, r5, 6b 

7:[/b] 

--- Quote End ---  

 

 

Another technique you can use is to place the exception entry point in its own section, 

then let the linker (and linker script) locate it where you want. You can play with the 

load memory address of the section if you need to relocate it at run time. 

 

Regards, 

--Scott 

 

PS -- You can download the u-boot source code if you want to dig into details: 

http://www.psyent.com/download (http://www.psyent.com/download)
0 Kudos
Altera_Forum
Honored Contributor II
464 Views

Sorry ... I forgot to post the actual exception dispatch -- again, this is all in the u-boot code if 

you want to dig in: 

<div class='quotetop'>QUOTE </div> 

--- Quote Start ---  

    .text 

    .align 4 

 

    .global _exception 

 

    .set noat 

    .set nobreak 

 

_exception: 

    /* SAVE ALL REGS -- this allows trap and unimplemented 

    * instruction handlers to be coded conveniently in C 

    */ 

    addi sp, sp, -(33*4) 

    stw r0, 0(sp) 

    stw r1, 4(sp) 

    stw r2, 8(sp) 

    stw r3, 12(sp) 

    stw r4, 16(sp) 

    stw r5, 20(sp) 

    stw r6, 24(sp) 

    stw r7, 28(sp) 

    stw r8, 32(sp) 

    stw r9, 36(sp) 

    stw r10, 40(sp) 

    stw r11, 44(sp) 

    stw r12, 48(sp) 

    stw r13, 52(sp) 

    stw r14, 56(sp) 

    stw r15, 60(sp) 

    stw r16, 64(sp) 

    stw r17, 68(sp) 

    stw r19, 72(sp) 

    stw r19, 76(sp) 

    stw r20, 80(sp) 

    stw r21, 84(sp) 

    stw r22, 88(sp) 

    stw r23, 92(sp) 

    stw r24, 96(sp) 

    stw r25, 100(sp) 

    stw r26, 104(sp) 

    stw r27, 108(sp) 

    stw r28, 112(sp) 

    stw r29, 116(sp) 

    stw r30, 120(sp) 

    stw r31, 124(sp) 

    rdctl et, estatus 

    stw et, 128(sp) 

 

    /* If interrupts are disabled -- software interrupt */ 

    rdctl et, estatus 

    andi et, et, 1 

    beq et, r0, 0f 

 

    /* If no interrupts are pending -- software interrupt */ 

    rdctl et, ipending 

    beq et, r0, 0f 

 

    /* HARDWARE INTERRUPT: Call interrupt handler */ 

    movhi r3, %hi(external_interrupt) 

    ori r3, r3, %lo(external_interrupt) 

    mov r4, sp  /* ptr to regs */ 

    callr r3 

 

    /* Return address fixup: execution resumes by re-issue of 

    * interrupted instruction at ea-4 (ea == r29). Here we do 

    * simple fixup to allow common exception return. 

    */ 

    ldw r3, 116(sp) 

    addi r3, r3, -4 

    stw r3, 116(sp) 

    br _exception_return 

 

0: 

    /* TRAP EXCEPTION */ 

    movhi r3, %hi(OPC_TRAP) 

    ori r3, r3, %lo(OPC_TRAP) 

    addi r1, ea, -4 

    ldw r1, 0(r1) 

    bne r1, r3, 1f 

    movhi r3, %hi(trap_handler) 

    ori r3, r3, %lo(trap_handler) 

    mov r4, sp  /* ptr to regs */ 

    callr r3 

    br _exception_return 

 

1: 

    /* UNIMPLEMENTED INSTRUCTION EXCEPTION */ 

    movhi r3, %hi(soft_emulation) 

    ori r3, r3, %lo(soft_emulation) 

    mov r4, sp  /* ptr to regs */ 

    callr r3 

 

/* Restore regsisters and return from exception*/ 

_exception_return: 

    ldw r1, 4(sp) 

    ldw r2, 8(sp) 

    ldw r3, 12(sp) 

    ldw r4, 16(sp) 

    ldw r5, 20(sp) 

    ldw r6, 24(sp) 

    ldw r7, 28(sp) 

    ldw r8, 32(sp) 

    ldw r9, 36(sp) 

    ldw r10, 40(sp) 

    ldw r11, 44(sp) 

    ldw r12, 48(sp) 

    ldw r13, 52(sp) 

    ldw r14, 56(sp) 

    ldw r15, 60(sp) 

    ldw r16, 64(sp) 

    ldw r17, 68(sp) 

    ldw r19, 72(sp) 

    ldw r19, 76(sp) 

    ldw r20, 80(sp) 

    ldw r21, 84(sp) 

    ldw r22, 88(sp) 

    ldw r23, 92(sp) 

    ldw r24, 96(sp) 

    ldw r25, 100(sp) 

    ldw r26, 104(sp) 

    ldw r27, 108(sp) 

    ldw r28, 112(sp) 

    ldw r29, 116(sp) 

    ldw r30, 120(sp) 

    ldw r31, 124(sp) 

    addi sp, sp, (33*4) 

    eret[/b] 

--- Quote End ---  

 

 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
464 Views

Thank you scott for code!  

I will try to dig your code but it looks too complicated (too big) for me and i don&#39;t understand this linker script http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/sad.gif I can show you my code that I wrote for testing my Nios II custom made optical encoder perifery and that shows how mutch I lerned in coding( it&#39;s just basic steps in code writing for nios II procesor) I used this Altera debug client (learned form altera provided Lab exercises) to load in my Cyclone II dev.kit(for 150$) I also tried nios II IDE but I don&#39;t know how to compile it and how to make this assembly code (I suppose this linker script is needed there am i right? http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/unsure.gif )  

 

here is my encoder perifery test code that works fine http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/smile.gif And in this week I added Interupt pin (avalon slave with interupt vector) and I need some extremly simple code to test it. 

.include "nios_macros.s" .equ enkoder, 0x00001800 .equ LEDG, 0x00001820# Cyclone II dev.kit Green LEDS .equ LEDR, 0x00001810# Cyclone II dev.kit RED LEDS /*enkoder register addres: 0 Speed 4 Caunter 8 Status*/ .global _start _start:     movia r2, enkoder     movia r3, LEDR     movia r5, LEDG loop:     ldwio r6, 4(r2) # Read Caunter register caunt value    stbio r6, 0(r3)  # Show caunter value by RED leds    nop     ldwio r6, 0(r2) //Read speed value     stbio r6, 0(r5) // show speed value by GREEN Leds     nop     br loop # infinit loop :)  

 

Previously on AVR 8bit procesors I didn&#39;t use eny linker scripts I codes in siple assembly but there was lot of simple examples also about interupts http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/smile.gif so I lerned wery fast, but now lerning Nios II is more dificult becose there are just few Lab exercises and they are incomplete (this first code I puted was from Lab exercise 4 and it is incomplete)
0 Kudos
Reply