NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL...

24
NIOS Interrupts Last updated 10/24/19

Transcript of NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL...

Page 1: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

NIOS Interrupts

Last updated 10/24/19

Page 2: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

2 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• 2 Options for dealing with interrupts

• Internal Interrupt Controller – IIC

• External Interrupt Controller - EIC

• The IIC has two versions• Legacy API

• Enhanced API

Page 3: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

3 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• On an interrupt or exception the processor• Saves the current status

• Disables HW interrupts

• Saves the next execution address (Program Counter)

• Transfers control to the exception handler

• What about all the registers?• NIOS supports shadow registers

• Remove the need to save the registers to the stack

Page 4: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

4 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• Support for 32 interrupt signals

• Interrupt # indicates inverse priority**

• We set these in QSYS

** Managed by the HAL SW

Page 5: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

5 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• The HAL Internal Interrupt framework uses a single exception controller

• We set the address for the “exception handler” when we instantiate the NIOS II processor

Page 6: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

6 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• The single Exception handler

• Handles exceptions and interrupts

• Exception handler keeps a table of ISR priorities

• To be included in the table – we must “register” the IRQ of each module

Page 7: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

7 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• Legacy Exception Handler Functions• ALT_LEGACY_INTERRUPT_API_PRESENT in system.h

alt_irq_register() alt_irq_interruptible()

alt_irq_disable() alt_irq_non_interruptible()

alt_irq_enable() alt_ic_irq_enabled()

alt_irq_disable_all()

alt_irq_enable_all()

Page 8: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

8 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• Enhanced Exception Handler Functions• ALT_ENHANCED_INTERRUPT_API_PRESENT in system.h

alt_ic_isr_register()

alt_ic_irq_disable()

alt_ic_irq_enable()

alt_irq_disable_all()

alt_irq_enable_all()

alt_ic_irq_enabled()

Page 9: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

9 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• Register prototype

int alt_ic_isr_register(

alt_u32 ic_id, interrupt controller ID

alt_u32 irq, interrupt ID

alt_isr_func isr, isr name

void * isr_context, pointer to any passed context

void * flags reserved - 0

);

Page 10: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

10 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts• Register prototype

interrupt controller ID – not used with IIC - 0

interrupt ID – from system.h

isr name – your choice

pointer to any passed context – e.g PIO input value

#define SW_PIO_HAS_IN 1

#define SW_PIO_HAS_OUT 0

#define SW_PIO_HAS_TRI 0

#define SW_PIO_IRQ 10

#define SW_PIO_IRQ_INTERRUPT_CONTROLLER_ID 0

#define SW_PIO_IRQ_TYPE "EDGE"

#define SW_PIO_NAME "/dev/sw_pio"

#define SW_PIO_RESET_VALUE 0

#define SW_PIO_SPAN 16

#define SW_PIO_TYPE "altera_avalon_pio"

Page 11: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

11 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• ISR prototype

void isr(void * context)

void pointers do not have a typevoid pointers can point to any typevoid pointers cannot be dereferencedvoid pointers can be cast to any typepointer arithmetic is not allowed with void pointers

Page 12: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

12 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

• Example

• Modify our counter project to increment the count based on a switch rising edge – via interrupt

• Use the edge capture flag as the signal to increment the counter

Page 13: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

13 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts• Edit sw_pio

Page 14: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

14 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

Page 15: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

15 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

Page 16: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

16 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

#include "system.h"

#include "altera_avalon_pio_regs.h"

#include "sys/alt_irq.h"

#include "alt_types.h"

#include <stdio.h>

Page 17: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

17 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

Choose a name for ISR

Create a global variable

Create a void * pointer to the global variable

Register the ISR – passing the context in via the

void * pointer

Create an appropriate type

pointer

Cast the context void * pointer to the appropriate

type pointer

Modify the appropriate type pointer as usual

ISR

foo

foo_ptr

void *

my_ptr

int *

context

cast

(*my_ptr)++;

incrementfoo

int

Page 18: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

18 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

// ISR Prototypevoid io_switch_isr(void * context);

Page 19: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

19 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

// Global variable to hold the value of the// edge capturevolatile int edge_val;

Page 20: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

20 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

// Cast the global variable to the required ISR// type of pointer - void *void * edge_val_ptr = (void *) &edge_val;

Page 21: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

21 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

// Register the interruptalt_ic_isr_register(

SW_PIO_IRQ_INTERRUPT_CONTROLLER_ID,SW_PIO_IRQ,io_switch_isr,edge_val_ptr,0x00

);

int alt_ic_isr_register(alt_u32 ic_id, interrupt controller IDalt_u32 irq, interrupt IDalt_isr_func isr, isr namevoid * isr_context, pointer to any passed contextvoid * flags reserved – 0

);

system.h

sys/alt_irq.h

Page 22: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

22 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

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 contextvolatile 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);

// Clear the edge capture registerIOWR_ALTERA_AVALON_PIO_EDGE_CAP(SW_PIO_BASE, 0);

} // end io_switch_isr

Page 23: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

23 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

int main(void){

printf("Entered main\n");

int 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++;

edge_val = 0;

printf("incrementing count : %i\n", count);

} else if (edge_val & 0x02){

count--;

edge_val = 0;

printf("decrementing count : %i\n", count);

}

// Output the count to the LEDs

IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, count);

}

} // end main

/*

* nios_interrupts.c

*

* Created on: Sep 20, 2018

* Author: johnsontimoj

*/

#include "system.h"

#include "altera_avalon_pio_regs.h"

#include "sys/alt_irq.h"

#include "alt_types.h"

#include <stdio.h>

// 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

volatile int edge_val = 0;

Page 24: NIOS Interrupts - Milwaukee School of Engineering · 2019-10-24 · NIOS Interrupts •HAL Framework –Interrupts •Register prototype interrupt controller ID –not used with IIC

24 © tjEE 3921

NIOS Interrupts

• HAL Framework – Interrupts

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 pointer - 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

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);

// Clear the edge capture register

IOWR_ALTERA_AVALON_PIO_EDGE_CAP(SW_PIO_BASE, 0);

} // end io_switch_isr