Interrupt Example

Download source: isa9.zip

This example causes the first four switches to trigger an interrupt that increments a counter. The main program continuously updates the count value, writing the count to the seven-segment displays.

The interrupts for sys2 are defined in system.h:

DevicedIRQ
TIMER 0
JTAG UART 1
PIO 2

main.c


01: /*
02:  * PIO test
03:  *
04:  */
05: 
06: #include <stdio.h>
07: #include <unistd.h>
08: #include "system.h"
09: #include "altera_avalon_pio_regs.h"
10: #include "sys/alt_irq.h"
11:  
12:  int n = 0;
13:  /* A variable to hold the value of the button pio edge capture register. */
14: volatile int edge_capture;
15: 
16: void init_pio();
17:  
18: int main()
19: {
20:     n = 0;
21:     init_pio();
22:     while (1) {
23:        IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, n);
24:   }
25:        
26:     return 0;
27: }
28:  
29:  /*******************************************************************
30:  * static void handle_button_interrupts( void* context, alt_u32 id)*
31:  *                                                                 *  
32:  * Handle interrupts from the buttons.                             *
33:  * This interrupt event is triggered by a button/switch press.     *
34:  * This handler sets *context to the value read from the button    *
35:  * edge capture register.  The button edge capture register        *
36:  * is then cleared and normal program execution resumes.           *
37:  * The value stored in *context is used to control program flow    *
38:  * in the rest of this program's routines.                         *
39:  ******************************************************************/
40: 
41: void handle_button_interrupts(void* context, alt_u32 id)
42: {
43:     /* Cast context to edge_capture's type. It is important that this be 
44:      * declared volatile to avoid unwanted compiler optimization.
45:      */
46:     volatile int* edge_capture_ptr = (volatile int*) context;
47:     /* Store the value in the Button's edge capture register in *context. */
48:     *edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(PIO_BASE);
49:     n++;
50:     /* Reset the Button's edge capture register. */
51:     IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_BASE, 0);
52: }
53: 
54: /* Initialize the pio. */
55: 
56: void init_pio()
57: {
58:     /* Recast the edge_capture pointer to match the alt_irq_register() function
59:      * prototype. */
60:     void* edge_capture_ptr = (void*) &edge_capture;
61:     /* Enable first four interrupts. */
62:     IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_BASE, 0xf);
63:     /* Reset the edge capture register. */
64:     IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_BASE, 0x0);
65:     /* Register the interrupt handler. */
66:     alt_irq_register( PIO_IRQ, edge_capture_ptr,
67:                       handle_button_interrupts );
68: }
69: 
70: 
71: #if defined(MAIN1)
72: int main()
73: {
74:   volatile int in,  out;
75:   while (1) 
76:   {
77:       in = IORD_ALTERA_AVALON_PIO_DATA(PIO_BASE);
78:       out = in;
79:       IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, out);
80:   }
81:  }
82:  #endif


Results

Watch program operation by debugging the program in hardware. Set a breakpoint in the middle of the button interrupt handler. Then allow the program to resume. The breakpoint will trigger when you toggle one of the first four switches. The screen shot below shows the view after setting the first switch. The edge_capture values is 1 (only first switch set) and the interrupt id = 2 (IRQ = 2)

Once you have set a breakpoint and triggered an interrupt, you can investigate the call chain that led to that breakpoint. Note that handle_button_interrupts is called by alt_irq_handler (see source).


Maintained by John Loomis, updated Sun Nov 16 23:29:39 2008