/* * nios_interrupts_updown.c * * Created on: Oct 17, 2018 * Author: johnsontimoj */ ///////////////////////////////////// // // Program to demonstrate interrupts // // this version does make use of the passed context // // inputs: sw0, sw1 - rising edges create interrupts // - incrementing/decrementing a count // ////////////////////////////////////// #include "system.h" // nios #include "altera_avalon_pio_regs.h" // #include "sys/alt_irq.h" // #include "alt_types.h" // alt_u8 #include #include // usleep // ISR Prototype void io_switch_isr(void * context); // Switch setup prototype void io_switch_setup(); // Global variable to hold the value of the // edge capture (context) volatile int edge_val = 0; int main(void){ printf("Entered main of nios_interrupts_updown.c\n"); int count; count = 0; // Configure the IO switches io_switch_setup(); // Loop and wait for edges to update the count while(1){ if(edge_val & 0x01){ count++; printf("incrementing count : %i\n", count); } else if(edge_val & 0x02){ count--; printf("decrementing count : %i\n", count); }// else do nothing // clear the edge_val to prevent ongoing counting edge_val = 0; // Output the count to the LEDs IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, count); } return 0; } // end main //////////////////////////////// // io_switch_setup // // HW: setup sw0 and sw1 with edge capture interrupts // // Enables interrupts and registers the ISR // // inputs: none // outputs: none ///////////////////////////////// void io_switch_setup(void){ // Enable interrupts on 2 switches IOWR_ALTERA_AVALON_PIO_IRQ_MASK(SW_PIO_BASE, 0x03); // Clear any existing interrupts IOWR_ALTERA_AVALON_PIO_EDGE_CAP(SW_PIO_BASE, 0x00); // Cast the global variable to the required ISR // type of pinter - void * void * edge_val_ptr; edge_val_ptr = (void *) &edge_val; // Register the interrupt alt_ic_isr_register(SW_PIO_IRQ_INTERRUPT_CONTROLLER_ID, SW_PIO_IRQ, io_switch_isr, edge_val_ptr, 0x00); } // end io_sw_setup //////////////////////////////// // io_switch_isr // // isr function to read which switch created the interrupt // and then set global variable to be used by the program // // inputs: a context that points to the global variable (void * pointer) // outputs: modifies the value of a global variable - holds switch inteerupt id // 01 for sw0, 10 for sw1 ///////////////////////////////// void io_switch_isr(void * context){ // expect the context passed to be a pointer // to the variable to hold the edge capture information // // create a pointer variable to hold the context volatile int * edge_ptr; edge_ptr = (volatile int *) context; // Read the edge capture register and assign the // value to the ptr variable *edge_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(SW_PIO_BASE); // Added usleep for a sloppy debouncer usleep(10000); // Clear the edge capture register IOWR_ALTERA_AVALON_PIO_EDGE_CAP(SW_PIO_BASE, 0); return; } // end io_switch_isr